繁体   English   中英

SQL Pivot 多列而不强制聚合

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM