Oracle 动态旋转

2024-04-09

我有下表。我需要根据 CCL 列创建列。 CCL 列中的值未知。我不知道从哪里开始。任何帮助,将不胜感激。

TABLEA

ID    CCL    Flag
1     john     x
1     adam     x
1     terry
1     rob      x
2     john     x

Query:

SELECT *
FROM TABLEA

Output:

ID  John  Adam  Terry  Rob
 1    x     x           x
 2    x       

与某些其他 RDMBS 相比,在 Oracle 中使用动态 sql 来获取执行时列未知的结果有点麻烦。

由于输出的记录类型尚不清楚,因此无法预先定义。

在 Oracle 11g 中,一种方法是使用无名过程来生成包含透视结果的临时表。

然后从该临时表中选择结果。

declare
  v_sqlqry clob;
  v_cols clob;
begin
  -- Generating a string with a list of the unique names
  select listagg(''''||CCL||''' as "'||CCL||'"', ', ') within group (order by CCL)
  into v_cols
  from 
  (
    select distinct CCL
    from tableA
  );

  -- drop the temporary table if it exists
  EXECUTE IMMEDIATE 'DROP TABLE tmpPivotTableA';
  EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF;

  -- A dynamic SQL to create a temporary table 
  -- based on the results of the pivot
  v_sqlqry := '
    CREATE GLOBAL TEMPORARY TABLE tmpPivotTableA
    ON COMMIT PRESERVE ROWS AS
    SELECT * 
    FROM (SELECT ID, CCL, Flag FROM TableA) src 
    PIVOT (MAX(Flag) FOR (CCL) IN ('||v_cols||')) pvt';

  -- dbms_output.Put_line(v_sqlqry); -- just to check how the sql looks like
  execute immediate v_sqlqry;
  
end;
/

select * from tmpPivotTableA;

Returns:

ID  adam john rob terry
--  ---- ---- --- -----
1   x    x    x
2        x      

你可以找到一个测试数据库小提琴

在 Oracle 11g 中,另一个很酷的技巧(由安东·谢弗 https://technology.amis.nl/author/anton-scheffer/)要使用的可以在这里找到blog https://technology.amis.nl/2006/05/24/dynamic-sql-pivoting-stealing-antons-thunder/。但您必须为其添加枢轴功能。
源码可以找到在这个邮编中 https://technology.amis.nl/wp-content/uploads/images/antonsPivoting.zip

之后 SQL 就可以像这样简单:

select * from 
table(pivot('SELECT ID, CCL, Flag FROM TableA'));

你会发现一个测试数据库小提琴

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Oracle 动态旋转 的相关文章

随机推荐