【问题标题】:How do you pivot some columns into rows using sql or t-sql如何使用 sql 或 t-sql 将某些列转换为行
【发布时间】:2020-05-28 13:59:29
【问题描述】:

这是桌子

Income|Expenses|Other|Department|Date

 2k   |      4k|  .5k|Marketing |2014-05-28
 52k  |      7k|  .1k|Sales     |2014-04-01

结果

Description|Value|Department|Date

 Income    |   2k|Marketing |2014-05-28
 Expenses  |   4k|Marketing |2014-05-28
 Other     |  .5k|Marketing |2014-05-28
 Income    |  52k|Sales     |2014-04-01
 Expenses  |   7k|Sales     |2014-04-01
 Other     |  .1k|Sales     |2014-04-01

其实我可以使用 SELECT + UNION 来得到结果,但要求是使用 Pivot。

如何使用 PIVOT 函数得到这个结果?

【问题讨论】:

    标签: sql sql-server pivot pivot-table


    【解决方案1】:

    您可以通过交叉应用取消您的价值观

    Select B.*
          ,A.Department
          ,A.Date
     From  YourTable A
     Cross Apply ( values ('Income'  ,Income  )
                         ,('Expences',Expenses)
                         ,('Other'   ,Other   )
                 ) B(Description,Value)
    

    【讨论】:

    • 很好的答案,但在 500k 行表上需要 4 秒。我稍后会尝试优化这个
    【解决方案2】:

    你可以使用UNPIVOT

    DECLARE @SampleData TABLE (Income VARCHAR(20), Expenses VARCHAR(20), Other VARCHAR(20), Department VARCHAR(20), Date [Date])
    INSERT INTO @SampleData VALUES
    ('2k ', '4k','.5k','Marketing','2014-05-28'),
    ('52k', '7k','.1k','Sales    ','2014-04-01')
    
    SELECT Description, Value, Department, Date 
    FROM @SampleData T
    UNPIVOT ([Value] FOR [Description] IN ([Income], [Expenses], [Other])) AS UNPVT
    

    结果:

    Description       Value                Department           Date
    ----------------- -------------------- -------------------- ----------
    Income            2k                   Marketing            2014-05-28
    Expenses          4k                   Marketing            2014-05-28
    Other             .5k                  Marketing            2014-05-28
    Income            52k                  Sales                2014-04-01
    Expenses          7k                   Sales                2014-04-01
    Other             .1k                  Sales                2014-04-01
    

    【讨论】:

    • 感谢这个非常快...但是如果某些 [value] 的收入、支出或其他为 NULL 怎么办?它不需要带有空值的行。你是怎么解决这个问题的?
    • 不客气! UNPIVOT 不考虑空值。在使用 unpivot 之前,您需要将 null 值转换为空格或其他内容。
    【解决方案3】:

    你可以使用apply

    select tt.Description, tt.Value, t.Department, t.Date
    from table t cross apply
         ( values ('Income', Income), ('Expenses', Expenses), ('Other', Other) 
         ) tt(Description, Value);
    

    【讨论】:

      【解决方案4】:

      只是为了好玩,这里有一个小技巧,可以在不使用动态 SQL 或声明所有列的情况下“动态”取消透视数据。

      示例

      Select Description = B.[Key]
            ,B.Value
            ,A.Department
            ,A.Date
       From  YourTable A
       Cross Apply ( Select [Key]
                            ,Value
                     From OpenJson( ( Select A.* for JSON Path,Without_Array_Wrapper)   )  
                     Where [Key] not in ('Department','Date')
                   ) B
      

      退货

      Description Value   Department  Date
      Income      2k      Marketing   2014-05-28
      Expenses    4k      Marketing   2014-05-28
      Other       .5k     Marketing   2014-05-28
      Income      52k     Sales       2014-04-01
      Expenses    7k      Sales       2014-04-01
      Other       .1k     Sales       2014-04-01
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-05-20
        • 1970-01-01
        • 1970-01-01
        • 2020-11-19
        • 2015-09-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多