将列转置为行 oracle
transpose column to row oracle
我有一个查询 return 这种形式的值(查询 return 超过 50 列)。
1-99transval 100-200transval 200-300transval ... 1-99nontransval 100...
50 90 80 67 58
对于行值。我希望将这些详细信息转换为列并采用以下形状:
Range Transval NonTransval
1-99 50 67
100-200 90 58
在纯 SQL 中,需要大量编码,因为您必须手动将 range 设置为值和范围之间根本没有关系。如果存在关系,您可以使用 CASE 表达式并动态构建范围 .
SQL> WITH DATA AS
2 (SELECT 50 "1-99transval",
3 90 "100-200transval",
4 80 "200-300transval",
5 67 "1-99nontransval",
6 58 "100-200nontransval",
7 88 "200-300nontransval"
8 FROM dual
9 )
10 SELECT '1-99' range,
11 "1-99transval" transval,
12 "1-99nontransval" nontransval
13 FROM DATA
14 UNION
15 SELECT '100-200' range,
16 "100-200transval",
17 "100-200nontransval" nontransval
18 FROM DATA
19 UNION
20 SELECT '200-300' range,
21 "200-300transval",
22 "200-300nontransval" nontransval
23 FROM DATA;
RANGE TRANSVAL NONTRANSVAL
------- ---------- -----------
1-99 50 67
100-200 90 58
200-300 80 88
从 Oracle 数据库 11g 第 1 版 及更高版本,您可以使用 UNPIVOT
SQL> WITH DATA AS
2 (SELECT 50 "1-99transval",
3 90 "100-200transval",
4 80 "200-300transval",
5 67 "1-99nontransval",
6 58 "100-200nontransval",
7 88 "200-300nontransval"
8 FROM dual
9 )
10 SELECT *
11 FROM DATA
12 UNPIVOT( (transval,nontransval)
13 FOR RANGE IN ( ("1-99transval","1-99nontransval") AS '1-99'
14 ,("100-200transval","100-200nontransval") AS '100-200'
15 ,("200-300transval","200-300nontransval") AS '200-300'));
RANGE TRANSVAL NONTRANSVAL
------- ---------- -----------
1-99 50 67
100-200 90 58
200-300 80 88
以上,在您的情况下,您需要将 WITH 子句替换为现有查询作为 子查询。您需要在 UNION.
中包含其他列
在 PL/SQL 中,您可以(滥用)使用 EXECUTE IMMEDIATE 并通过提取获得 "range" 动态 sql.
中的 列名称
尽管如此,modify/rewrite 您尚未显示的现有查询会更好。
如果您使用的是 Oracle 11g 版本,则可以使用 UNPIVOT 功能。
CREATE TABLE DATA AS
SELECT 50 "1-99transval",
90 "100-200transval",
80 "200-300transval",
67 "1-99nontransval",
58 "100-200nontransval",
88 "200-300nontransval"
FROM dual
SELECT *
FROM DATA
UNPIVOT( (Transval,NonTransval) FOR Range IN ( ("1-99transval","1-99nontransval") as '1-99'
,("100-200transval","100-200nontransval") as '100-200'
,("200-300transval","200-300nontransval") as '200-300'))
我有一个查询 return 这种形式的值(查询 return 超过 50 列)。
1-99transval 100-200transval 200-300transval ... 1-99nontransval 100...
50 90 80 67 58
对于行值。我希望将这些详细信息转换为列并采用以下形状:
Range Transval NonTransval
1-99 50 67
100-200 90 58
在纯 SQL 中,需要大量编码,因为您必须手动将 range 设置为值和范围之间根本没有关系。如果存在关系,您可以使用 CASE 表达式并动态构建范围 .
SQL> WITH DATA AS
2 (SELECT 50 "1-99transval",
3 90 "100-200transval",
4 80 "200-300transval",
5 67 "1-99nontransval",
6 58 "100-200nontransval",
7 88 "200-300nontransval"
8 FROM dual
9 )
10 SELECT '1-99' range,
11 "1-99transval" transval,
12 "1-99nontransval" nontransval
13 FROM DATA
14 UNION
15 SELECT '100-200' range,
16 "100-200transval",
17 "100-200nontransval" nontransval
18 FROM DATA
19 UNION
20 SELECT '200-300' range,
21 "200-300transval",
22 "200-300nontransval" nontransval
23 FROM DATA;
RANGE TRANSVAL NONTRANSVAL
------- ---------- -----------
1-99 50 67
100-200 90 58
200-300 80 88
从 Oracle 数据库 11g 第 1 版 及更高版本,您可以使用 UNPIVOT
SQL> WITH DATA AS
2 (SELECT 50 "1-99transval",
3 90 "100-200transval",
4 80 "200-300transval",
5 67 "1-99nontransval",
6 58 "100-200nontransval",
7 88 "200-300nontransval"
8 FROM dual
9 )
10 SELECT *
11 FROM DATA
12 UNPIVOT( (transval,nontransval)
13 FOR RANGE IN ( ("1-99transval","1-99nontransval") AS '1-99'
14 ,("100-200transval","100-200nontransval") AS '100-200'
15 ,("200-300transval","200-300nontransval") AS '200-300'));
RANGE TRANSVAL NONTRANSVAL
------- ---------- -----------
1-99 50 67
100-200 90 58
200-300 80 88
以上,在您的情况下,您需要将 WITH 子句替换为现有查询作为 子查询。您需要在 UNION.
中包含其他列在 PL/SQL 中,您可以(滥用)使用 EXECUTE IMMEDIATE 并通过提取获得 "range" 动态 sql.
中的 列名称尽管如此,modify/rewrite 您尚未显示的现有查询会更好。
如果您使用的是 Oracle 11g 版本,则可以使用 UNPIVOT 功能。
CREATE TABLE DATA AS
SELECT 50 "1-99transval",
90 "100-200transval",
80 "200-300transval",
67 "1-99nontransval",
58 "100-200nontransval",
88 "200-300nontransval"
FROM dual
SELECT *
FROM DATA
UNPIVOT( (Transval,NonTransval) FOR Range IN ( ("1-99transval","1-99nontransval") as '1-99'
,("100-200transval","100-200nontransval") as '100-200'
,("200-300transval","200-300nontransval") as '200-300'))