取消激活多个列并将其分组到新列中

时间:2016-02-21 05:36:56

标签: sql-server tsql sql-server-2012 unpivot

我正在使用客户数据,其中包含多个参数,如预计单位,预计值,数量单位,数量值,Parm单位,每个月的Parm值。

每个参数都以月份名为前缀,例如JAN_Projected单位,JAN_预计值,JAN_Quantity单位,JAN_数量值,JAN_ Parm单位,JAN_ Parm值。

这是我桌子的架构:

CREATE TABLE [dbo].[tbl_forum_data](
    [Sno] [float] NULL,
    [JAN_Projected units] [float] NULL,
    [JAN_Projected value] [float] NULL,
    [JAN_Quantity units] [float] NULL,
    [JAN_Quantity value] [float] NULL,
    [JAN_Parm Units  ] [float] NULL,
    [JAN_Parm Value  ] [float] NULL,
    [FEB_Projected units] [float] NULL,
    [FEB_Projected value] [float] NULL,
    [FEB_Quantity units] [float] NULL,
    [FEB_Quantity value] [float] NULL,
    [FEB_Parm Units  ] [float] NULL,
    [FEB_Parm Value  ] [float] NULL,
    [MAR_Projected units] [float] NULL,
    [MAR_Projected value] [float] NULL,
    [MAR_Quantity units] [float] NULL,
    [MAR_Quantity value] [float] NULL,
    [MAR_Parm Units  ] [float] NULL,
    [MAR_Parm Value  ] [float] NULL
) ON [PRIMARY]

我想根据每个月对每个预计单位,预计值,数量单位,数量值,parm单位和参数值进行分组,如下面的截图

Sample Output

如果无法做到这一点,至少我想将列更改为行,并将单位分组为单独的列和值,以分隔列,如下所示。

Output2

我尝试进行交叉连接但是我能够将值放入行中。以下是我使用的代码:

select Sno
       ,G.EventName
       ,G.EventDate
from [db_Temp].[dbo].[tbl_forum_data] as T
  cross apply (values ([JAN_Projected units], 'JAN_Projected units'),
([JAN_ Projected value], 'JAN_ Projected value'),
([JAN_Quantity units], 'JAN_Quantity units'),
([JAN_ Quantity value], 'JAN_ Quantity value'),
([JAN_ Parm Units  ], 'JAN_ Parm Units'),
([JAN_ Parm Value  ], 'JAN_ Parm Value'),
([FEB_ Projected units], 'FEB_ Projected units'),
([FEB_ Projected value], 'FEB_ Projected value'),
([FEB_Quantity units], 'FEB_Quantity units'),
([FEB_ Quantity value], 'FEB_ Quantity value'),
([FEB_ Parm Units  ], 'FEB_ Parm Units'),
([FEB_ Parm Value  ], 'FEB_ Parm Value'),
([MAR_ Projected units], 'MAR_ Projected units'),
([MAR_ Projected value], 'MAR_ Projected value'),
([MAR_ Quantity units], 'MAR_ Quantity units'),
([MAR_ Quantity value], 'MAR_ Quantity value'),
([MAR_ Parm Units  ], 'MAR_ Parm Units'),
([MAR_ Parm Value  ], 'MAR_ Parm Value')) as G(EventDate, EventName);

非常感谢任何帮助。小提琴手SQL Schema的链接。

1 个答案:

答案 0 :(得分:0)

此脚本显示了两种执行此操作的方法。

  1. 使用CROSS APPLY生成具有所需列的行
  2. 使用UNPIVOT
  3. 使用MAX(CASE ...) + pivot
    CREATE TABLE #tbl_forum_data(
        [Sno] [float] NULL,
        [JAN_Projected units] [float] NULL, [JAN_Projected value] [float] NULL,[JAN_Quantity units] [float] NULL,
        [JAN_Quantity value] [float] NULL, [JAN_Parm Units  ] [float] NULL,[JAN_Parm Value  ] [float] NULL,
        [FEB_Projected units] [float] NULL, [FEB_Projected value] [float] NULL, [FEB_Quantity units] [float] NULL,
        [FEB_Quantity value] [float] NULL, [FEB_Parm Units  ] [float] NULL, [FEB_Parm Value  ] [float] NULL,
        [MAR_Projected units] [float] NULL, [MAR_Projected value] [float] NULL, [MAR_Quantity units] [float] NULL,
        [MAR_Quantity value] [float] NULL, [MAR_Parm Units  ] [float] NULL, [MAR_Parm Value  ] [float] NULL
    );
    INSERT INTO #tbl_forum_data([Sno],
        [JAN_Projected units],[JAN_Projected value],[JAN_Quantity units],[JAN_Quantity value],[JAN_Parm Units  ],[JAN_Parm Value  ],
        [FEB_Projected units],[FEB_Projected value],[FEB_Quantity units],[FEB_Quantity value],[FEB_Parm Units  ],[FEB_Parm Value  ],
        [MAR_Projected units],[MAR_Projected value],[MAR_Quantity units],[MAR_Quantity value],[MAR_Parm Units  ],[MAR_Parm Value  ]
    )
    VALUES(1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18);
    
    -- using cross apply/union all
    SELECT
        Sno,[Month],[Projected units],[Projected value],[Quantity units],[Quantity value],[Parm Units],[Parm Value]
    FROM
        #tbl_forum_data
        CROSS APPLY (
            SELECT 'JAN' AS [Month], 0 AS [MonthSort],
                   [JAN_Projected units] AS [Projected units], [JAN_Projected value] AS [Projected value],
                   [JAN_Quantity units]  AS [Quantity units] , [JAN_Quantity value]  AS [Quantity value] ,
                   [JAN_Parm Units  ]    AS [Parm Units]     , [JAN_Parm Value  ]    AS [Parm Value]
            UNION ALL
            SELECT 'FEB' AS [Month], 1 AS [MonthSort],
                   [FEB_Projected units] AS [Projected units], [FEB_Projected value] AS [Projected value],
                   [FEB_Quantity units]  AS [Quantity units] , [FEB_Quantity value]  AS [Quantity value] ,
                   [FEB_Parm Units  ]    AS [Parm Units]     , [FEB_Parm Value  ]    AS [Parm Value]
            UNION ALL
            SELECT 'MAR' AS [Month], 2 AS [MonthSort],
                   [MAR_Projected units] AS [Projected units], [MAR_Projected value] AS [Projected value],
                   [MAR_Quantity units]  AS [Quantity units] , [MAR_Quantity value]  AS [Quantity value] ,
                   [MAR_Parm Units  ]    AS [Parm Units]     , [MAR_Parm Value  ]    AS [Parm Value]
        ) AS up
    ORDER BY
        Sno,[MonthSort];
    
    -- using unpivot / pivot (using MAX(CASE ...) for multi column pivot)
    SELECT
        Sno,[Month],
        [Projected units]=MAX(CASE WHEN category='Projected units' THEN value END),
        [Projected value]=MAX(CASE WHEN category='Projected value' THEN value END),
        [Quantity units]=MAX(CASE WHEN category='Quantity units' THEN value END),
        [Quantity value]=MAX(CASE WHEN category='Quantity value' THEN value END),
        [Parm Units]=MAX(CASE WHEN category='Parm Units  ' THEN value END),
        [Parm Value]=MAX(CASE WHEN category='Parm Value  ' THEN value END)
    FROM
        (
            SELECT
                Sno,[Month]=LEFT(DataPoint,3),category=SUBSTRING(DataPoint,5,LEN(DataPoint)),value
            FROM
                #tbl_forum_data
                UNPIVOT (
                    value FOR DataPoint IN (
                        [JAN_Projected units],[JAN_Quantity units],[JAN_Parm Units  ],
                        [FEB_Projected units],[FEB_Quantity units],[FEB_Parm Units  ],
                        [MAR_Projected units],[MAR_Quantity units],[MAR_Parm Units  ]
                    )
                ) AS up_units
            UNION ALL
            SELECT
                Sno,[Month]=LEFT(DataPoint,3),category=SUBSTRING(DataPoint,5,LEN(DataPoint)),value
            FROM
                #tbl_forum_data
                UNPIVOT (
                    value FOR DataPoint IN (
                        [JAN_Projected value],[JAN_Quantity value],[JAN_Parm value  ],
                        [FEB_Projected value],[FEB_Quantity value],[FEB_Parm value  ],
                        [MAR_Projected value],[MAR_Quantity value],[MAR_Parm value  ]
                    )
                ) AS up_units
        ) AS up
    GROUP BY
        Sno,[Month]
    ORDER BY
        Sno,CASE [Month] WHEN 'JAN' THEN 0 WHEN 'FEB' THEN 1 ELSE 2 END;
    
    DROP TABLE #tbl_forum_data;
    

    1和2的结果:

    +-----+-------+-----------------+-----------------+----------------+----------------+------------+------------+
    | Sno | Month | Projected units | Projected value | Quantity units | Quantity value | Parm Units | Parm Value |
    +-----+-------+-----------------+-----------------+----------------+----------------+------------+------------+
    |   1 | JAN   |               1 |               2 |              3 |              4 |          5 |          6 |
    |   1 | FEB   |               7 |               8 |              9 |             10 |         11 |         12 |
    |   1 | MAR   |              13 |              14 |             15 |             16 |         17 |         18 |
    +-----+-------+-----------------+-----------------+----------------+----------------+------------+------------+