我正在尝试将一个表分为两列(我们在表上做了一些规范化,但是需要创建一个向后兼容的视图)。我的新数据结构是这样:
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列)
答案 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)
答案 1 :(得分:0)
选择* 从 ( 选择market_year,产品,价值 来自#products p )src 枢 ( 总和(值) 用于(啤酒,玉米,牛肉)中的产品 )piv;
尝试此操作将帮助您获得一些想法