我有一个包含 31 列的表,其中包含一个月中每一天的值,我想创建一个转置表,如下例所示。数据库中的真实数据真的很大,所以我不指望用Excel来解决这个问题。这可以通过使用 SQL 来完成还是有任何工具可以做到这一点?
原表
+----+--------------+--------------+-----+---------------+---------------+
| ID | price_date_1 | price_date_2 | ... | price_date_30 | price_date_31 |
+----+--------------+--------------+-----+---------------+---------------+
| A | 1 | 2 | ... | 0 | 1 |
| B | 2 | 3 | ... | 1 | 2 |
+----+--------------+--------------+-----+---------------+---------------+
Run Code Online (Sandbox Code Playgroud)
新表
+---------------+---+---+
| Price | A | B |
+---------------+---+---+
| price_date_1 | 1 | 2 |
| price_date_2 | 2 | 3 |
| ... | | |
| price_date_30 | 0 | 1 |
| price_date_31 | 1 | 2 |
+---------------+---+---+
Run Code Online (Sandbox Code Playgroud)
在SQL服务器2005年或以后,在UNPIVOT
和PIVOT
运营商可以使用:
样本数据:
DECLARE @Source AS TABLE
(
ID char(1) PRIMARY KEY,
PD1 integer NOT NULL,
PD2 integer NOT NULL,
PD3 integer NOT NULL,
PD4 integer NOT NULL,
PD5 integer NOT NULL
);
INSERT @Source
(ID, PD1, PD2, PD3, PD4, PD5)
VALUES
('A', 1, 2, 3, 4, 5),
('B', 6, 7, 8, 9, 0);
Run Code Online (Sandbox Code Playgroud)
询问:
SELECT
Pvt.Price,
Pvt.A,
Pvt.B
FROM @Source AS s
UNPIVOT
(
Val
FOR Price IN (PD1, PD2, PD3, PD4, PD5)
) AS Unpvt
PIVOT
(
MAX(Val)
FOR ID IN (A, B)
) AS Pvt;
Run Code Online (Sandbox Code Playgroud)
输出:
?????????????????
? Price ? A ? B ?
?????????????????
? PD1 ? 1 ? 6 ?
? PD2 ? 2 ? 7 ?
? PD3 ? 3 ? 8 ?
? PD4 ? 4 ? 9 ?
? PD5 ? 5 ? 0 ?
?????????????????
Run Code Online (Sandbox Code Playgroud)
执行计划:
SELECT
f1.Price,
A = MAX(CASE WHEN s.ID = 'A' THEN f1.Val END),
B = MAX(CASE WHEN s.ID = 'B' THEN f1.Val END)
FROM @Source AS s
CROSS APPLY
(
SELECT 'PD1', s.PD1 UNION ALL
SELECT 'PD2', s.PD2 UNION ALL
SELECT 'PD3', s.PD3 UNION ALL
SELECT 'PD4', s.PD4 UNION ALL
SELECT 'PD5', s.PD5
) AS f1 (Price, Val)
GROUP BY
f1.Price;
Run Code Online (Sandbox Code Playgroud)