SQL 将行转为列
SQL Pivot Rows to Column
以为这很容易,但我遇到了麻烦。我需要旋转(或反旋转)一个包含 100,000 多行的 table(称为 da_LMP_downloads)。我从这个开始:table_before
之前:
集市日 |节点| Node_Type | LMP_Value| HE1 | HE2| HE 3|.......|HE24|
2012 年 10 月 1 日 |AEC|界面 | LMP | 17.82 | 16.44 | 16.45
2012 年 10 月 1 日 |AEC|界面 |中冶 | .14 | .16 | .62
2012 年 10 月 1 日 |AEC|界面 |多层板 | -.38 | -.34 | .34
但需要它在枢轴后看起来像这样:table_after
之后:
Market_Day |节点 |贺 |达林普 | daMCC | daMLC
2012 年 10 月 1 日 |工程建设委员会 | 1 | 17.82 | .14 | -.38
2012 年 10 月 1 日 |工程建设委员会 | 2| 16.44| .16 | -.34
2012 年 10 月 1 日 |工程建设委员会 | 3 | 16.45 | .62 | .34
如果您的 dbms 是 SQL 服务器,那么您可以使用 CROSS APPLY 和 VALUES 来实现 "unpivot" 部分,但是您还需要一个小的 "pivot" 操作为此, GROUP BY 将起作用。请注意,这仅适用于 SQL 服务器,其他数据库对 unpivot/pivot.
的语法有很大不同
/* input looks like this...
Market_Day Node Node_Type LMP_Value HE1 HE2 .... HE24
2012-10-01 AEC Interface LMP 17.82 16.44 .... 19.77
*/
SELECT
sq.Market_Day
, sq.Node
, sq.Node_Type
, sq.HE
, MAX(sq.daLMP) AS daLMP
, MAX(sq.daMCC) AS daMCC
, MAX(sq.daMLC) AS daMLC
FROM (
SELECT
t.Market_Day
, t.Node
, t.Node_Type
, ca.HE
, CASE WHEN LMP_Value = 'LMP' THEN ca.val END AS daLMP
, CASE WHEN LMP_Value = 'MCC' THEN ca.val END AS daMCC
, CASE WHEN LMP_Value = 'MLC' THEN ca.val END AS daMLC
FROM Table1 t
CROSS APPLY (
VALUES
(1, HE1)
, (2, HE2)
, (3, HE3)
, (4, HE4)
, (5, HE5)
, (6, HE6)
, (7, HE7)
, (8, HE8)
, (9, HE9)
, (10, HE10)
, (11, HE11)
, (12, HE12)
, (13, HE13)
, (14, HE14)
, (15, HE15)
, (16, HE16)
, (17, HE17)
, (18, HE18)
, (19, HE19)
, (20, HE20)
, (21, HE21)
, (22, HE22)
, (23, HE23)
, (24, HE24)
) AS ca (HE, val)
) AS sq
GROUP BY
sq.Market_Day
, sq.Node
, sq.Node_Type
, sq.HE
注意 TSQL 实际上确实同时具有 "pivot" 和 "unpivot" 运算符,但我发现使用交叉 apply/values 既高效又易于实现。
以为这很容易,但我遇到了麻烦。我需要旋转(或反旋转)一个包含 100,000 多行的 table(称为 da_LMP_downloads)。我从这个开始:table_before
之前:
集市日 |节点| Node_Type | LMP_Value| HE1 | HE2| HE 3|.......|HE24|
2012 年 10 月 1 日 |AEC|界面 | LMP | 17.82 | 16.44 | 16.45
2012 年 10 月 1 日 |AEC|界面 |中冶 | .14 | .16 | .62
2012 年 10 月 1 日 |AEC|界面 |多层板 | -.38 | -.34 | .34
但需要它在枢轴后看起来像这样:table_after
之后:
Market_Day |节点 |贺 |达林普 | daMCC | daMLC
2012 年 10 月 1 日 |工程建设委员会 | 1 | 17.82 | .14 | -.38
2012 年 10 月 1 日 |工程建设委员会 | 2| 16.44| .16 | -.34
2012 年 10 月 1 日 |工程建设委员会 | 3 | 16.45 | .62 | .34
如果您的 dbms 是 SQL 服务器,那么您可以使用 CROSS APPLY 和 VALUES 来实现 "unpivot" 部分,但是您还需要一个小的 "pivot" 操作为此, GROUP BY 将起作用。请注意,这仅适用于 SQL 服务器,其他数据库对 unpivot/pivot.
的语法有很大不同/* input looks like this...
Market_Day Node Node_Type LMP_Value HE1 HE2 .... HE24
2012-10-01 AEC Interface LMP 17.82 16.44 .... 19.77
*/
SELECT
sq.Market_Day
, sq.Node
, sq.Node_Type
, sq.HE
, MAX(sq.daLMP) AS daLMP
, MAX(sq.daMCC) AS daMCC
, MAX(sq.daMLC) AS daMLC
FROM (
SELECT
t.Market_Day
, t.Node
, t.Node_Type
, ca.HE
, CASE WHEN LMP_Value = 'LMP' THEN ca.val END AS daLMP
, CASE WHEN LMP_Value = 'MCC' THEN ca.val END AS daMCC
, CASE WHEN LMP_Value = 'MLC' THEN ca.val END AS daMLC
FROM Table1 t
CROSS APPLY (
VALUES
(1, HE1)
, (2, HE2)
, (3, HE3)
, (4, HE4)
, (5, HE5)
, (6, HE6)
, (7, HE7)
, (8, HE8)
, (9, HE9)
, (10, HE10)
, (11, HE11)
, (12, HE12)
, (13, HE13)
, (14, HE14)
, (15, HE15)
, (16, HE16)
, (17, HE17)
, (18, HE18)
, (19, HE19)
, (20, HE20)
, (21, HE21)
, (22, HE22)
, (23, HE23)
, (24, HE24)
) AS ca (HE, val)
) AS sq
GROUP BY
sq.Market_Day
, sq.Node
, sq.Node_Type
, sq.HE
注意 TSQL 实际上确实同时具有 "pivot" 和 "unpivot" 运算符,但我发现使用交叉 apply/values 既高效又易于实现。