使用SQL在Oracle

问题描述 投票:0回答:1
样本表数据:

ID label value app_id --- ----- ----- ------ 120 A Alpha 1 120 B Beta 1 120 C Class 1 120 D Delta 1 120 C Alpha 2 120 D Beta 2 120 E Class 2 120 F Delta 2

建设性查询是 WITH data( ID, label, value, app_id ) AS ( SELECT 120, 'A', 'Alpha', 1 FROM dual UNION ALL SELECT 120, 'B', 'Beta' , 1 FROM dual UNION ALL SELECT 120, 'C', 'Class', 1 FROM dual UNION ALL SELECT 120, 'D', 'Delta', 1 FROM dual UNION ALL SELECT 120, 'C', 'Alpha', 2 FROM dual UNION ALL SELECT 120, 'D', 'Beta' , 2 FROM dual UNION ALL SELECT 120, 'E', 'Class', 2 FROM dual UNION ALL SELECT 120, 'F', 'Delta', 2 FROM dual ) SELECT * FROM data


Id
label
值 app_idalpha11120cclass1120d2120eclass2120f1211121Q贝塔 r delphi1121Ssine1121Q代码 贝塔 2121P22指望输出:SELECT * FROM data WHERE ID = 120 AND app_id = 1; app_id A B C D ID ------ ------ ----- ----- ----- ----- 1 Alpha Beta Class Delta 120 SELECT * FROM data WHERE ID = 120 AND app_id = 2; app_id C D E F ID ------ ------ ----- ----- ----- ----- 2 Alpha Beta Class Delta 120 你可以做什么 SELECT * FROM data PIVOT ( MAX(value) FOR label IN ('A' AS "A", 'B' AS "B",'C' AS "C",'D' AS "D") ) WHERE ID = 120 AND app_id = 1
120 a
120 B 贝塔
delta 1
120 c alpha 2
120 d 贝塔
delta 2
P 代码
1 121
2 121 r
delphi
121 S sine
当静态枢轴语句可以转换为包含两个相应参数的函数

CREATE OR REPLACE FUNCTION Get_Pivoted_Labels( i_id data.id%type, i_app_id data.app_id%type ) RETURN SYS_REFCURSOR IS v_recordset SYS_REFCURSOR; v_sql VARCHAR2(32767); v_cols VARCHAR2(32767); BEGIN SELECT LISTAGG( ''''||label||''' AS "'||label||'"' , ',' ) WITHIN GROUP ( ORDER BY label ) INTO v_cols FROM ( SELECT DISTINCT label FROM data WHERE ID = i_id AND app_id = i_app_id ); v_sql := 'SELECT * FROM data PIVOT ( MAX(value) FOR label IN ( '|| v_cols ||' ) ) WHERE ID = :id AND app_id = :aid'; OPEN v_recordset FOR v_sql USING i_id, i_app_id; RETURN v_recordset; END; / 在哪个辅助查询中,其中选择了label

列的辅助查询,用于确定要在光标返回光标中使用的字符串(
v_cols
),以将其连接到主SQL字符串中,以返回类型

'A' AS "A", 'B' AS "B",'C' AS "C",'D' AS "D"的值。 enter image description here援引

SYS_REFCURSOR
sql oracle-database plsql pivot
1个回答
2
投票
从SQL开发人员的控制台。

示例

带有生成的SQL语句

如果选择列表中的列顺序很重要,则使用以下代码来创建函数

VAR rc REFCURSOR VAR v_id NUMBER VAR v_app_id NUMBER EXEC :rc := Get_Pivoted_Labels(:v_id,:v_app_id); PRINT rc

    
这是一个非常普遍的问题,出于简单的原因是答案是“否”。
使用Oracle数据库,每个选择语句都必须具有固定且已知的“形状”(列的数量,其名称和数据类型)。在最近的版本中,似乎有“多态表函数”似乎打破了此规则,但实际上它们没有:在解析语句时计算出“形状”,因此在执行开始之前将其固定并知道。
您不想要“多态”(在解析时变形),您需要真正的“动态”(根据数据在执行时间更改形状)。甲骨文不这样做。
最接近您可以使用一个SQL语句获得的最接近的是,精确输出包含XML或JSON的列。然后,调用数据库的程序将负责将结果转换为行和列。 其他替代方案是执行一个选择以获取列名并生成第二个选择以获取所需的结果。我写了一个功能来帮助这样做:
https://stewashton.wordpress.com/2018/05/30/impreved-pivot-function/

我不会证明这些替代方案中的任何一个,因为它们不会直接回答您的问题。没有问您的问题直接答案。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.