Oracle SQL:将多列转置为行
Posted
技术标签:
【中文标题】Oracle SQL:将多列转置为行【英文标题】:Oracle SQL: Transpose Multiple Columns to Row 【发布时间】:2018-10-26 11:48:57 【问题描述】:将多列转置为行的最佳方法
给定:
A B C D E F G
FYQ1 11 10 8 6 1 0 0
FYQ2 11 10 8 7 2 0 0
FYQ3 11 11 11 10 5 4 0
FYQ4 11 11 11 10 5 4 0
必填:
FYQ1 FYQ2 FYQ3 FYQ4
A 11 11 11 11
B 10 10 11 11
C 8 8 11 11
D 6 7 10 10
E 1 2 5 5
F 0 0 4 4
G 0 0 0 0
【问题讨论】:
为什么不想使用聚合函数呢?您使用的是什么版本的 Oracle? 12c,我们可以使用聚合吗??, 【参考方案1】:我看到你编辑了你的问题。
您可以尝试将条件聚合函数与UNION ALL
一起使用
CREATE TABLE T(
Name varchar(50),
A int,
B int,
C int,
D int,
E int,
F int,
G int
);
INSERT INTO T VALUES ('FYQ1',11,10,8 ,6,1,0,0);
INSERT INTO T VALUES ('FYQ2',11,10,8 ,7,2,0,0);
INSERT INTO T VALUES ('FYQ3',11,11,11,10,5,4,0);
INSERT INTO T VALUES ('FYQ4',11,11,11,10,5,4,0);
查询 1:
SELECT 'A' as " ",
MAX(CASE WHEN NAME = 'FYQ1' THEN A END) FYQ1,
MAX(CASE WHEN NAME = 'FYQ2' THEN A END) FYQ2,
MAX(CASE WHEN NAME = 'FYQ3' THEN A END) FYQ3,
MAX(CASE WHEN NAME = 'FYQ4' THEN A END) FYQ4
FROM T
UNION ALL
SELECT 'C',
MAX(CASE WHEN NAME = 'FYQ1' THEN C END),
MAX(CASE WHEN NAME = 'FYQ2' THEN C END),
MAX(CASE WHEN NAME = 'FYQ3' THEN C END),
MAX(CASE WHEN NAME = 'FYQ4' THEN C END)
FROM T
UNION ALL
SELECT 'D',
MAX(CASE WHEN NAME = 'FYQ1' THEN D END),
MAX(CASE WHEN NAME = 'FYQ2' THEN D END),
MAX(CASE WHEN NAME = 'FYQ3' THEN D END),
MAX(CASE WHEN NAME = 'FYQ4' THEN D END)
FROM T
UNION ALL
SELECT 'E',
MAX(CASE WHEN NAME = 'FYQ1' THEN E END),
MAX(CASE WHEN NAME = 'FYQ2' THEN E END),
MAX(CASE WHEN NAME = 'FYQ3' THEN E END),
MAX(CASE WHEN NAME = 'FYQ4' THEN E END)
FROM T
UNION ALL
SELECT 'F',
MAX(CASE WHEN NAME = 'FYQ1' THEN F END),
MAX(CASE WHEN NAME = 'FYQ2' THEN F END),
MAX(CASE WHEN NAME = 'FYQ3' THEN F END),
MAX(CASE WHEN NAME = 'FYQ4' THEN F END)
FROM T
UNION ALL
SELECT 'G',
MAX(CASE WHEN NAME = 'FYQ1' THEN G END),
MAX(CASE WHEN NAME = 'FYQ2' THEN G END),
MAX(CASE WHEN NAME = 'FYQ3' THEN G END),
MAX(CASE WHEN NAME = 'FYQ4' THEN G END)
FROM T
Results:
| | FYQ1 | FYQ2 | FYQ3 | FYQ4 |
|---|------|------|------|------|
| A | 11 | 11 | 11 | 11 |
| C | 8 | 8 | 11 | 11 |
| D | 6 | 7 | 10 | 10 |
| E | 1 | 2 | 5 | 5 |
| F | 0 | 0 | 4 | 4 |
| G | 0 | 0 | 0 | 0 |
【讨论】:
我们可以使用 WITH 子句优化它吗?只需执行一次所有 T 表计算。【参考方案2】:您可以使用 unpivot 和 pivot,我分享示例。
CREATE TABLE T(
Name varchar(50),
A int,
B int,
C int,
D int,
E int,
F int,
G int
);
INSERT INTO T VALUES ('FYQ1',11,10,8 ,6,1,0,0);
INSERT INTO T VALUES ('FYQ2',11,10,8 ,7,2,0,0);
INSERT INTO T VALUES ('FYQ3',11,11,11,10,5,4,0);
INSERT INTO T VALUES ('FYQ4',11,11,11,10,5,4,0);
SELECT words,
fyq1,
fyq2,
fyq3,
fyq4
FROM (
SELECT name,
fyq1 AS words,
value
FROM (
SELECT *
FROM t) unpivot ( (value) FOR (fyq1,fyq2,fyq3,fyq4) IN (a,
b,
c,
d,
e,
f,
g) )) pivot( SUM(value) FOR name IN ('FYQ1' AS fyq1,
'FYQ2' AS fyq2,
'FYQ3' AS fyq3,
'FYQ4' AS fyq4) )
ORDER BY words;
【讨论】:
您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。以上是关于Oracle SQL:将多列转置为行的主要内容,如果未能解决你的问题,请参考以下文章