SQLServer-同一列上的多个透视

SQLServer-同一列上的多个透视,sql,sql-server,pivot,Sql,Sql Server,Pivot,我很想知道我是否可以像这样在sql server中的同一列上执行多个透视: WITH T(ID, NAME, MSNAME, PLANED, ACTUAL) AS ( SELECT 1, '45rpm', 'Raised to Supplier', '2014-12-17', '2015-12-17' UNION ALL SELECT 1, '45rpm', 'Base Test Date', '2014-12-18', '2015-12-18' UNION ALL SE

我很想知道我是否可以像这样在sql server中的同一列上执行多个透视:

WITH T(ID, NAME, MSNAME, PLANED, ACTUAL)
AS (
    SELECT 1, '45rpm', 'Raised to Supplier', '2014-12-17', '2015-12-17' UNION ALL
    SELECT 1, '45rpm', 'Base Test Date', '2014-12-18', '2015-12-18' UNION ALL
    SELECT 1, '45rpm', 'Washing Approval', '2014-12-19', '2015-12-19'
)
SELECT ID, NAME
  , MAX(CASE WHEN MSNAME LIKE 'Raised to Supplier' THEN PLANED END) AS 'Raised to Supplier (PLANED)'
  , MAX(CASE WHEN MSNAME LIKE 'Base Test Date' THEN PLANED END) AS 'Base Test Date (PLANED)'
  , MAX(CASE WHEN MSNAME LIKE 'Washing Approval' THEN PLANED END) AS 'Washing Approval (PLANED)'
  , MAX(CASE WHEN MSNAME LIKE 'Raised to Supplier' THEN ACTUAL END) AS 'Raised to Supplier (ACTUAL)'
  , MAX(CASE WHEN MSNAME LIKE 'Base Test Date' THEN ACTUAL END) AS 'Base Test Date (ACTUAL)'
  , MAX(CASE WHEN MSNAME LIKE 'Washing Approval' THEN ACTUAL END) AS 'Washing Approval (ACTUAL)'
FROM T
GROUP BY ID, NAME
对于“计划的”列,它运行良好,但我无法添加第二列“实际的”(如上面的示例所示)↑)

编辑:

PIVOT关键字几乎没有限制,其中一个限制已在此处讨论过,即SQL server不支持PIVOT中的多个聚合-由Giorgos评论[类似PIVOT(min(),max(),sum()…)]

有3种备选方案来应对这种情况:

  • 带有不带PIVOT关键字的case语句的通用解决方案(如上面第一个示例所示)
  • 首先取消数据透视,然后进行数据透视(在聚合之前增加行并合并列)[由@bluefeet回答]
  • 复制第二次聚合的列[由@NoDisplayName回答]

  • 了解了这一点后,我认为这个问题的标题应该是:单轴中的多个聚合(),而不是现有的聚合。要旋转
    Multiple column
    ,您需要使用
    Multiple PIVOT的
    而不是
    Multiple aggregates
    。试试这个

    SELECT ID,
           NAME,
           Max([Raised to Supplier(PLANED)])[Raised to Supplier(PLANED)],
           Max([Base Test Date(PLANED)])[Base Test Date(PLANED)],
           Max([Washing Approval(PLANED)])[Washing Approval(PLANED)],
           Max([Raised to Supplier(ACTUAL)])[Raised to Supplier(ACTUAL)],
           Max([Base Test Date(ACTUAL)])[Base Test Date(ACTUAL)],
           Max([Washing Approval(ACTUAL)])[Washing Approval(ACTUAL)]
    FROM   (SELECT 1 ID,'45rpm' NAME,'Raised to Supplier' + '(PLANED)' MSNAME_pl,'Raised to Supplier' + '(ACTUAL)' MSNAME_ac,'2014-12-17' PLANED,'2015-12-17' ACTUAL
            UNION ALL
            SELECT 1,'45rpm','Base Test Date' + '(PLANED)','Base Test Date' + '(ACTUAL)','2014-12-18','2015-12-18'
            UNION ALL
            SELECT 1,'45rpm','Washing Approval' + '(PLANED)','Washing Approval' + '(ACTUAL)','2014-12-19','2015-12-19') a
           PIVOT ( Max(PLANED)
                 FOR MSNAME_pl IN ([Raised to Supplier(PLANED)],
                                   [Base Test Date(PLANED)],
                                   [Washing Approval(PLANED)]) ) AS p1 
    
            PIVOT ( MAX(ACTUAL) 
                  FOR MSNAME_ac IN ([Raised to Supplier(ACTUAL)],
                                    [Base Test Date(ACTUAL)],
                                    [Washing Approval(ACTUAL)])) p2
    GROUP BY ID, NAME
    

    SQL Server不允许在多个列上进行数据透视,实际上我建议先取消对
    计划的
    实际的
    列的透视,然后将数据透视到所需的最终结果中

    您没有指定正在使用的SQL Server版本,但可以使用UNPIVOT函数,也可以使用CROSS APPLY将多列转换为多行。基本语法为:

    select 
      id,
      name, 
      new_col = msname + '_' + col,
      value
    from t
    cross apply
    (
      select 'planed', planed union all
      select 'actual', actual
    ) c (col, value);
    
    请参阅。这会将数据转换为以下格式:

    | ID |  NAME |                   NEW_COL |      VALUE |
    |----|-------|---------------------------|------------|
    |  1 | 45rpm | Raised to Supplier_planed | 2014-12-17 |
    |  1 | 45rpm | Raised to Supplier_actual | 2015-12-17 |
    |  1 | 45rpm |     Base Test Date_planed | 2014-12-18 |
    |  1 | 45rpm |     Base Test Date_actual | 2015-12-18 |
    |  1 | 45rpm |   Washing Approval_planed | 2014-12-19 |
    |  1 | 45rpm |   Washing Approval_actual | 2015-12-19 |
    
    现在,您有了所需的新列名以及单列中的值,而不是多列中的值。现在您可以将数据透视到最终结果中:

    select id, name, 
      [Raised to Supplier_planed], [Raised to Supplier_actual],
      [Base Test Date_planed], [Base Test Date_actual],
      [Washing Approval_planed], [Washing Approval_actual]
    from
    (
      select 
        id,
        name, 
        new_col = msname + '_' + col,
        value
      from t
      cross apply
      (
        select 'planed', planed union all
        select 'actual', actual
      ) c (col, value)
    ) d
    pivot
    (
      max(value)
      for new_col in ([Raised to Supplier_planed], [Raised to Supplier_actual],
                      [Base Test Date_planed], [Base Test Date_actual],
                      [Washing Approval_planed], [Washing Approval_actual])
    ) p;
    
    | ID |  NAME | RAISED TO SUPPLIER_PLANED | RAISED TO SUPPLIER_ACTUAL | BASE TEST DATE_PLANED | BASE TEST DATE_ACTUAL | WASHING APPROVAL_PLANED | WASHING APPROVAL_ACTUAL |
    |----|-------|---------------------------|---------------------------|-----------------------|-----------------------|-------------------------|-------------------------|
    |  1 | 45rpm |                2014-12-17 |                2015-12-17 |            2014-12-18 |            2015-12-18 |              2014-12-19 |              2015-12-19 |
    
    参见。这将给出相同的最终结果:

    select id, name, 
      [Raised to Supplier_planed], [Raised to Supplier_actual],
      [Base Test Date_planed], [Base Test Date_actual],
      [Washing Approval_planed], [Washing Approval_actual]
    from
    (
      select 
        id,
        name, 
        new_col = msname + '_' + col,
        value
      from t
      cross apply
      (
        select 'planed', planed union all
        select 'actual', actual
      ) c (col, value)
    ) d
    pivot
    (
      max(value)
      for new_col in ([Raised to Supplier_planed], [Raised to Supplier_actual],
                      [Base Test Date_planed], [Base Test Date_actual],
                      [Washing Approval_planed], [Washing Approval_actual])
    ) p;
    
    | ID |  NAME | RAISED TO SUPPLIER_PLANED | RAISED TO SUPPLIER_ACTUAL | BASE TEST DATE_PLANED | BASE TEST DATE_ACTUAL | WASHING APPROVAL_PLANED | WASHING APPROVAL_ACTUAL |
    |----|-------|---------------------------|---------------------------|-----------------------|-----------------------|-------------------------|-------------------------|
    |  1 | 45rpm |                2014-12-17 |                2015-12-17 |            2014-12-18 |            2015-12-18 |              2014-12-19 |              2015-12-19 |
    

    好吧,你试试看吧?TSQL不支持PIVOT中的多个聚合。很难选择任何一个答案。
    @NoDisplayName
    @bluefeet
    都显示了他们的创造力,我测试的两个答案都正常工作。现在是我说“Eeny,meeny,miny,moe”的时候了