在两个值列上透视表

时间:2019-05-07 06:14:47

标签: sql-server

我正在尝试将一个表分为两列(我们在表上做了一些规范化,但是需要创建一个向后兼容的视图)。我的新数据结构是这样:

CREATE TABLE #Products (
  product VARCHAR(30),
  market_year INT,
  value INT,
  description varchar(20));

INSERT INTO #Products VALUES('Corn', 2003, 100, 'bad');
INSERT INTO #Products VALUES('Beer', 2003, 200, 'not so bad');
INSERT INTO #Products VALUES('Beef', 2003, 150, 'good');

INSERT INTO #Products VALUES('Corn', 2004, 10, 'doo');
INSERT INTO #Products VALUES('Beer', 2004, 20, 'foo');
INSERT INTO #Products VALUES('Beef', 2004, 10, 'bar');

外观如下:

SELECT * FROM #Products p;

product market_year value   description
Corn        2003    100     bad
Beer        2003    200     not so bad
Beef        2003    150     good
Corn        2004    10      doo
Beer        2004    20      foo
Beef        2004    10      bar

我需要的结果应如下所示:

market_year |corn_value |corn_description | beer_value | beer_description |beef_value | beef_description
2003        | 100       |bad              | 150        | NOT so bad       |150        | good
2003        | 10        |doo              | 15         | foo              |15         | bar

我知道我可以用两个单独的语句来做到这一点,每个语句都以market_year为轴,并按market_year加入它们,但这将需要将该表读取两次。有没有更优雅的方法来解决此问题? (我的表中大约有700万条记录,分为70列,需要还原为140列)

2 个答案:

答案 0 :(得分:1)

您可以尝试使用动态数据透视

声明两个变量@CONTENT以代表CASE WHEN的透视SQL查询MAX 然后使用@sql连接查询sql,并使用execute动态执行此sql。

DECLARE @SQL VARCHAR(MAX),@CONTENT VARCHAR(MAX)
SELECT  @CONTENT = STUFF((
    SELECT ', '+'MAX(CASE WHEN product = '''+ product + ''' THEN [VALUE] END) AS '''+product+'_value'',
        MAX(CASE WHEN product = '''+ product + ''' THEN [description] END) AS '''+product+'_value'''
    FROM #Products 
    FOR XML PATH(''),TYPE).value('(./text())[1]','VARCHAR(MAX)')
  ,1,2,'')

SELECT @SQL = 'SELECT market_year,' + @CONTENT + ' FROM #Products GROUP BY market_year';
execute(@SQL)

sqlfiddle

答案 1 :(得分:0)

选择* 从 (   选择market_year,产品,价值   来自#products p )src 枢 (   总和(值)   用于(啤酒,玉米,牛肉)中的产品 )piv;

尝试此操作将帮助您获得一些想法