取消透视多列并分组为新列
Unpivot multiple columns and group into new columns
我正在处理一个客户数据,它有多个参数,例如列中每个月的预计单位、预计值、数量单位、数量值、Parm 单位、Parm 值。
每个参数都带有月份名称前缀,例如 JAN_Projected 单位、JAN_ 预计值、JAN_Quantity 单位、JAN_ 数量值、JAN_ Parm 单位、JAN_ Parm 值。
这是我的 table 的架构:
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]
我想根据每个月对每个预计单位、预计值、数量单位、数量值、参数单位和参数值进行分组,如下面的屏幕截图
如果那不可能,至少我想将列更改为行并将单位分组为单独的列,将值分组为单独的列,如下所示。
我尝试进行交叉连接,但我能够将值放入行中。下面是我使用的代码:
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);
非常感谢任何帮助。 Link 为提琴手 SQL Schema。
此脚本显示了执行此操作的两种方法。
- 使用
CROSS APPLY
生成具有所需列的行
- 使用
UNPIVOT
+ 枢轴使用 MAX(CASE ...)
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 |
+-----+-------+-----------------+-----------------+----------------+----------------+------------+------------+
我正在处理一个客户数据,它有多个参数,例如列中每个月的预计单位、预计值、数量单位、数量值、Parm 单位、Parm 值。
每个参数都带有月份名称前缀,例如 JAN_Projected 单位、JAN_ 预计值、JAN_Quantity 单位、JAN_ 数量值、JAN_ Parm 单位、JAN_ Parm 值。
这是我的 table 的架构:
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]
我想根据每个月对每个预计单位、预计值、数量单位、数量值、参数单位和参数值进行分组,如下面的屏幕截图
如果那不可能,至少我想将列更改为行并将单位分组为单独的列,将值分组为单独的列,如下所示。
我尝试进行交叉连接,但我能够将值放入行中。下面是我使用的代码:
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);
非常感谢任何帮助。 Link 为提琴手 SQL Schema。
此脚本显示了执行此操作的两种方法。
- 使用
CROSS APPLY
生成具有所需列的行 - 使用
UNPIVOT
+ 枢轴使用MAX(CASE ...)
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 |
+-----+-------+-----------------+-----------------+----------------+----------------+------------+------------+