【问题标题】:Pivoting Multiple Columns Based On a Single Column基于单列旋转多列
【发布时间】:2013-11-07 12:12:55
【问题描述】:

我尝试遵循此网站上的其他几个建议,但由于某种原因无法完成。

基本上我试图从这个任务表中获取:

| TaskID | ProjectID | TaskType | TaskDate1 | TaskDate2 |
---------------------------------------------------------
|      1 |         1 |    Type4 |  20130401 |  20130506 |
|      2 |         1 |    Type0 |  20130412 |  20130508 |
|      3 |         1 |    Type2 |  20130420 |  20130517 |

致那个人:

| ProjectID | Type0Date1 | Type0Date2 | Type2Date1 | Type2Date2 | Type4Date1 | Type4Date2 |
---------------------------------------------------------
|         1 |   20130412 |   20130508 |   20130420 |   20130517 |   20130401 |   20130506 |

每个项目都必须有几个预定义的任务(由它们的类型标识)。这些任务有很多属性,但我对 2 个日期感兴趣,最好将它们全部放在每个项目的一行中。

我可以轻松地将其旋转到其中一列:PIVOT (MAX(TaskDate1) FOR TaskType IN ([Type0],[Type2],[Type4]))

我尝试复制 TaskType 列并围绕它为 TaskDate2 做另一个旋转,但这不会给我一行。

我也无法理解如何首先不旋转表格将我带到我需要的地方,就像其他一些帖子中针对类似问题的建议一样。

如果有一种可扩展的方式来做到这一点(比如旋转更多的列),那就太好了。

谢谢。

【问题讨论】:

    标签: sql sql-server sql-server-2008-r2 pivot


    【解决方案1】:

    您可以获得所需的结果,但由于您需要在多个列(TaskDate1TaskDate2)上进行 PIVOT,因此我首先将两列取消旋转为多行。

    由于您使用的是 SQL Server 2008+,因此您可以使用 UNPIVOT 函数或 CROSS APPLY 来转换多个列。基本语法是:

    select projectid,
      col = TaskType+col,
      value
    from yourtable
    cross apply
    (
      values 
        ('Date1', TaskDate1),
        ('Date2', TaskDate2)
    ) c(col, value)
    

    SQL Fiddle with Demo。这会将您的数据转换为易于使用的格式:

    | PROJECTID |        COL |                        VALUE |
    |-----------|------------|------------------------------|
    |         1 | Type4Date1 | April, 01 2013 00:00:00+0000 |
    |         1 | Type4Date2 |   May, 06 2013 00:00:00+0000 |
    |         1 | Type0Date1 | April, 12 2013 00:00:00+0000 |
    |         1 | Type0Date2 |   May, 08 2013 00:00:00+0000 |
    

    获得这种格式的数据后,您可以应用 PIVOT 函数来获取每个 max(value)col

    select projectId,
      Type0Date1, Type0Date2, 
      Type2Date1, Type2Date2,
      Type4Date1, Type4Date2
    from
    (
      select projectid,
        col = TaskType+col,
        value
      from yourtable
      cross apply
      (
        values 
          ('Date1', TaskDate1),
          ('Date2', TaskDate2)
      ) c(col, value)
    ) d
    pivot
    (
      max(value)
      for col in (Type0Date1, Type0Date2, Type2Date1, Type2Date2,
                  Type4Date1, Type4Date2)
    ) piv;
    

    SQL Fiddle with Demo

    如果每个 ProjectId 的值数量有限,上述版本会很好用,但如果每个项目的任务数量未知,则需要使用动态 SQL 来获得最终结果:

    DECLARE @cols AS NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX)
    
    select @cols = STUFF((SELECT ',' + QUOTENAME(TaskType+col) 
                        from yourtable
                        cross apply
                        (
                          select 'Date1', 1 union all
                          select 'Date2', 2
                        ) c(col, so)
                        group by col, tasktype, so
                        order by tasktype, so
                FOR XML PATH(''), TYPE
                ).value('.', 'NVARCHAR(MAX)') 
            ,1,1,'')
    
    set @query = 'SELECT projectid, ' + @cols + ' 
                from 
                (
                  select projectid,
                    col = TaskType+col,
                    value
                  from yourtable
                  cross apply
                  (
                    values 
                      (''Date1'', TaskDate1),
                      (''Date2'', TaskDate2)
                  ) c(col, value)
                ) x
                pivot 
                (
                    max(value)
                    for col in (' + @cols + ')
                ) p '
    
    execute sp_executesql @query
    

    SQL Fiddle with Demo。这些将给出结果:

    | PROJECTID |                   TYPE0DATE1 |                 TYPE0DATE2 |                   TYPE2DATE1 |                 TYPE2DATE2 |                   TYPE4DATE1 |                 TYPE4DATE2 |
    |-----------|------------------------------|----------------------------|------------------------------|----------------------------|------------------------------|----------------------------|
    |         1 | April, 12 2013 00:00:00+0000 | May, 08 2013 00:00:00+0000 | April, 20 2013 00:00:00+0000 | May, 17 2013 00:00:00+0000 | April, 01 2013 00:00:00+0000 | May, 06 2013 00:00:00+0000 |
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-05
      • 2022-01-23
      • 2019-01-02
      • 1970-01-01
      • 2019-07-23
      • 1970-01-01
      相关资源
      最近更新 更多