[英]SQL Pivot multiple columns without forcing aggregate
我需要转出一些非规范化数据,但它会重复,所以我需要它转出列,然后返回多行。
我有一张这样的桌子
INSERT #TheTable
VALUES
('StockCode' ,'a'),
('Warehouse' ,'b'),
('TrnYear' ,'c'),
('TrnMonth' ,'d'),
('EntryDate' ,'e'),
('TrnTime' ,'f'),
('StockCode' ,'1'),
('Warehouse' ,'2'),
('TrnYear' ,'3'),
('TrnMonth' ,'4'),
('EntryDate' ,'5'),
('TrnTime' ,'6')
但是当我旋转时它只返回一行:
SELECT StockCode,
Warehouse,
TrnYear,
TrnMonth,
TrnTime,
EntryDate
FROM #TheTable AS src
PIVOT (MAX(column_value)
FOR COLUMN_NAME in ([TrnYear], [TrnMonth], [EntryDate], [TrnTime], [StockCode], [Warehouse])) AS piv
结果:
StockCode Warehouse TrnYear TrnMonth TrnTime EntryDate
-------------------------------------------------------------
a b c d f e
但我需要它回来
StockCode Warehouse TrnYear TrnMonth TrnTime EntryDate
-------------------------------------------------------------
a b c d f e
1 2 3 4 5 6
您可以先使用窗口函数,然后使用条件聚合:
select
max(case when column_name = 'StockCode' then column_value end) StockCode,
max(case when column_name = 'Warehouse' then column_value end) Warehouse,
max(case when column_name = 'TrnYear' then column_value end) TrnYear,
max(case when column_name = 'TrnMonth' then column_value end) TrnMonth,
max(case when column_name = 'TrnTime' then column_value end) TrnTime,
max(case when column_name = 'EntryDate' then column_value end) EntryDate
from (
select t.*,
row_number() over(partition by column_name order by column_value) rn
from #TheTable t
) t
group by rn
您可以使用ROW_NUMBER()
分析函数:
SELECT *
FROM
(
SELECT column_name, column_value,
ROW_NUMBER() OVER (PARTITION BY column_name ORDER BY column_value) AS rn
FROM #TheTable
) q
PIVOT
( MAX(column_value)
FOR column_name in ([TrnYear], [TrnMonth], [EntryDate], [TrnTime], [StockCode], [Warehouse])
) AS piv
或更动态地,使用:
DECLARE @cols AS NVARCHAR(MAX), @query AS NVARCHAR(MAX)
SET @cols = ( SELECT STRING_AGG(column_name,',')
FROM (SELECT DISTINCT column_name
FROM [#TheTable] ) q );
SET @query =
N'SELECT *
FROM
(
SELECT column_name, column_value,
ROW_NUMBER() OVER
(PARTITION BY [column_name] ORDER BY [column_value]) AS rn
FROM [#TheTable]
) f
PIVOT
(
MAX([column_value]) FOR [column_name] IN (' + @cols + N')
) AS piv '
EXEC sp_executesql @query;
问题是每组列名我都需要一个 row_number 。 所以下面的工作
SELECT DISTINCT TrnYear,
TrnMonth,
EntryDate,
TrnTime,
StockCode,
Warehouse
FROM
(SELECT (ROW_NUMBER() OVER (ORDER BY dw_view_change_event_nr) - 1) / 6 + 1 AS rn,
COLUMN_NAME ,
column_value
FROM
#TheTable AS tmp) AS src PIVOT (MAX(column_value)
FOR COLUMN_NAME in ([TrnYear], [TrnMonth], [EntryDate], [TrnTime], [StockCode], [Warehouse])) AS piv
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.