我有问题在SQL Server 2008中将行切换到列,反之亦然,我已尝试对解决方案进行任何查询,但我没有得到正确的结果。
我有一张表如下:
declare @tmpTable table (name varchar(20), date_ date, sales_code char(1), sales smallint, earned int) insert into @tmpTable values ('Robert', '2016/8/1', 'A', 2, 30), ('Robert', '2016/8/1', 'B', 3, 45), ('Robert', '2016/8/2', 'B', 1, 15), ('Robert', '2016/8/3', 'B', 2, 30), ('Jhon', '2016/8/1', 'A', 3, 45), ('Jhon', '2016/8/2', 'A', 3, 45), ('Jhon', '2016/8/3', 'B', 2, 30) select * from @tmpTable;
结果:
Name date_ sales_code sales earned ------ ---------- ---------- ----- ------ Robert 2016-08-01 A 2 30 Robert 2016-08-01 B 3 45 Robert 2016-08-02 B 1 15 Robert 2016-08-03 B 2 30 Jhon 2016-08-01 A 3 45 Jhon 2016-08-02 A 3 45 Jhon 2016-08-03 B 2 30
然后,我有下一个查询:
select * from ( select name, 'sales_code' as category, date_, sales_code from ( select * from ( SELECT name, date_ ,STUFF((SELECT ', ' + sales_code [text()] FROM @tmpTable WHERE date_ = t.date_ FOR XML PATH(''), TYPE) .value('.','NVARCHAR(MAX)'),1,2,' ') sales_code ,STUFF((SELECT ', ' + convert(varchar(max), sales) [text()] FROM @tmpTable WHERE date_ = t.date_ FOR XML PATH(''), TYPE) .value('.','NVARCHAR(MAX)'),1,2,' ') sales ,STUFF((SELECT ', ' + convert(varchar(max), earned) [text()] FROM @tmpTable WHERE date_ = t.date_ FOR XML PATH(''), TYPE) .value('.','NVARCHAR(MAX)'),1,2,' ') earned FROM @tmpTable t GROUP BY name, date_ ) as a ) as a ) as a pivot ( max(sales_code) FOR date_ IN ([2016/8/1], [2016/8/2], [2016/8/3]) )as pv union all select * from ( select name, 'sales' as category, date_, sales from ( select * from ( SELECT name, date_ ,STUFF((SELECT ', ' + sales_code [text()] FROM @tmpTable WHERE date_ = t.date_ FOR XML PATH(''), TYPE) .value('.','NVARCHAR(MAX)'),1,2,' ') sales_code ,STUFF((SELECT ', ' + convert(varchar(max), sales) [text()] FROM @tmpTable WHERE date_ = t.date_ FOR XML PATH(''), TYPE) .value('.','NVARCHAR(MAX)'),1,2,' ') sales ,STUFF((SELECT ', ' + convert(varchar(max), earned) [text()] FROM @tmpTable WHERE date_ = t.date_ FOR XML PATH(''), TYPE) .value('.','NVARCHAR(MAX)'),1,2,' ') earned FROM @tmpTable t GROUP BY name, date_ ) as a ) as a ) as a pivot ( max(sales) FOR date_ IN ([2016/8/1], [2016/8/2], [2016/8/3]) )as pv union all select * from ( select name, 'earned' as category, date_, earned from ( select * from ( SELECT name, date_ ,STUFF((SELECT ', ' + sales_code [text()] FROM @tmpTable WHERE date_ = t.date_ FOR XML PATH(''), TYPE) .value('.','NVARCHAR(MAX)'),1,2,' ') sales_code ,STUFF((SELECT ', ' + convert(varchar(max), sales) [text()] FROM @tmpTable WHERE date_ = t.date_ FOR XML PATH(''), TYPE) .value('.','NVARCHAR(MAX)'),1,2,' ') sales ,STUFF((SELECT ', ' + convert(varchar(max), earned) [text()] FROM @tmpTable WHERE date_ = t.date_ FOR XML PATH(''), TYPE) .value('.','NVARCHAR(MAX)'),1,2,' ') earned FROM @tmpTable t GROUP BY name, date_ ) as a ) as a ) as a pivot ( max(earned) FOR date_ IN ([2016/8/1], [2016/8/2], [2016/8/3]) )as pv
它将显示结果:
name category 2016/8/1 2016/8/2 2016/8/3 ------- -------- -------- ------- -------- Jhon sales_code A, B, A B, A B, B Robert sales_code A, B, A B, A B, B Jhon sales 2, 3, 3 1, 3 2, 2 Robert sales 2, 3, 3 1, 3 2, 2 Jhon earned 30, 45, 45 15, 45 30, 30 Robert earned 30, 45, 45 15, 45 30, 30
但是,我想得到以下结果:
name category 2016/8/1 2016/8/2 2016/8/3 ---- -------- -------- -------- -------- Robert sales_code A, B B B Robert sales 2, 3 1 2 Robert earned 30, 45 15 30 Jhon sales_code A A B Jhon sales 3 3 2 Jhon earned 45 45 30
非常感谢您的帮助。
答案 0 :(得分:0)
首先你需要取消数据的移动..要做到这一点,所有数据类型都匹配很多,所以你需要将2个数字列转换为varchars。
在你想要获取每个名称的组合值,date_之前仍然使用东西,但是使用distinct来获取名称,date_值一次。
取消投影后,您只需再次转动。
SELECT *
FROM ( SELECT DISTINCT
Name,
date_,
sales_code = STUFF((SELECT ', ' + sales_code
FROM @tmpTable t2
WHERE t2.Name = t.Name AND t2.date_ = t.date_
FOR XML PATH('')), 1, 2, ''),
sales = STUFF((SELECT ', ' + CONVERT(VARCHAR, sales)
FROM @tmpTable t2
WHERE t2.Name = t.Name AND t2.date_ = t.date_
FOR XML PATH('')), 1, 2, ''),
earned = STUFF((SELECT ', ' + CONVERT(VARCHAR, earned)
FROM @tmpTable t2
WHERE t2.Name = t.Name AND t2.date_ = t.date_
FOR XML PATH('')), 1, 2, '')
FROM @tmpTable t) t
UNPIVOT (
val
FOR category IN (sales_code, sales, earned)
) up
PIVOT (
MAX(val)
FOR date_ IN ([2016-08-01], [2016-08-02], [2016-08-03])
) p
ORDER BY name DESC,
category DESC