sql - 在 Oracle 中使用动态列进行透视
问题描述
我是新的 oracle 数据库我有一个如下表
ID Passengers Age Eligible
123456 Ben 65 Yes
123456 Mary 58 Yes
123458 Stephanie 37 Yes
123458 Aaron 32 Yes
123458 Caroline 18 No
我想获得动态列名称为 Age1、Age2、Age3 等的结果。如下所示
ID Age1 Age2 Age3
123456 65 58 NULL
123458 37 32 18
它可以通过 STUFF 和 Dynamic Pivot 来实现,SQL Server
但我不知道如何在Oracle
谁能指导我如何动态地做到这一点Oracle
解决方案
SYS_REFCURSOR
在存储函数中(例如,使用 PL/SQL 而不是直接使用 SQL)可以用于获取动态生成的结果集(例如Dynamic Pivot)。在这种情况下,会生成一个用于条件聚合的字符串:
CREATE OR REPLACE FUNCTION get_passengers_rs RETURN SYS_REFCURSOR IS
v_recordset SYS_REFCURSOR;
v_sql VARCHAR2(32767);
v_str VARCHAR2(32767);
BEGIN
SELECT LISTAGG('MAX(CASE WHEN rn = '||lvl||' THEN age||''(''||passengers||'')'' END)
AS "Age'||lvl||'"' ,',') WITHIN GROUP (ORDER BY 0)
INTO v_str
FROM ( SELECT level AS lvl
FROM dual
CONNECT BY level <= (SELECT MAX(COUNT(*)) FROM t GROUP BY ID ) ) t;
v_sql :=
'SELECT ID, '|| v_str ||'
FROM
(
SELECT t.*,
ROW_NUMBER() OVER (PARTITION BY ID ORDER BY 0) AS rn
FROM t
)
GROUP BY ID';
OPEN v_recordset FOR v_sql;
RETURN v_recordset;
END;
我还添加了乘客的姓名,以便很好地区分每个数据。
然后运行以下代码:
VAR rc REFCURSOR
EXEC :rc := get_passengers_rs;
PRINT rc
从 SQL Developer 的命令行中查看预期的结果集。
上面的代码为当前存在的数据生成这个 SQL 字符串(v_sql )
SELECT ID, MAX(CASE WHEN rn = 1 THEN age||'('||passengers||')' END) AS "Age1",
MAX(CASE WHEN rn = 2 THEN age||'('||passengers||')' END) AS "Age2",
MAX(CASE WHEN rn = 3 THEN age||'('||passengers||')' END) AS "Age3"
FROM
(
SELECT t.*,
ROW_NUMBER() OVER (PARTITION BY ID ORDER BY 0) AS rn
FROM t
)
GROUP BY ID
产生
ID Age1 Age2 Age3
123456 58(Marie) 65(Ben)
123458 32(Aaron) 18(Caroline) 37(Stephanie)
作为结果集。
推荐阅读
- python - 重新启用 spacy 的解析器组件给出错误
- python - 如何有效地执行字典合并?
- python-3.x - 功能外观,需要生成一个随机选择 4 个选项的列表
- angular - 运行业力单元测试用例“引发未知 [对象对象]”时出错
- python - 我的时间序列图如何从“00:00”开始并在“23:00”结束?两边没有空格
- asp.net-mvc - 在 Bamboo 中设置 NSIS 构建
- java - 从另一个类调用时函数崩溃应用程序但从 MainActivity.java 调用时不会
- python - 如何用 Python 重新排列一个复杂的方程
- tensorflow - 视频对象分类建议
- highcharts - HIghchart Treemap - 在图例单击时添加双击事件