【问题标题】:Dynamic row to column conversion with total column使用总列的动态行到列转换
【发布时间】:2021-07-26 18:04:25
【问题描述】:

表名:样本数据

  id | State_Assign
-----------------
a10  | FL
a11  | AL
a11  | PH
a12  | MA
a12  | GL

我是 oracle 的新手,我尝试过 Pivot 但正在寻找动态解决方案,状态分配的数量是动态的,今天可以为 a11 id 分配 2 个,但明天可以更改为 3 个。 附上所需的输出截图 谢谢!

【问题讨论】:

  • 是否存在将分配的最大状态数? (除了 50...)试图了解您是否需要它是真正动态的,所以直到运行时您才知道结果集中将有多少列;这通常表明这应该在应用程序/报告层中完成。
  • 是的!列还包含除状态值之外的其他值,但它们是 2 或 3 个值。

标签: oracle plsql pivot oracle-sqldeveloper dynamic-pivot


【解决方案1】:

基本上你可以使用这样一个包含条件聚合逻辑的静态解决方案

SELECT id,
       MAX(CASE WHEN rn = 1 THEN State_Assign END) AS sa1,
       MAX(CASE WHEN rn = 2 THEN State_Assign END) AS sa2,
       .......
       .......
       COUNT(*) AS total
  FROM (SELECT s.*, ROW_NUMBER() OVER (PARTITION BY id ORDER BY 0) AS rn 
          FROM sampledata s)
 GROUP BY id 
 ORDER BY id 

可能会创建一个存储函数来生成 select 语句,该语句将根据表的当前值产生动态结果,例如

CREATE OR REPLACE FUNCTION Get_Pivoted_States RETURN SYS_REFCURSOR IS
  v_recordset SYS_REFCURSOR;
  v_sql       VARCHAR2(32767);
  v_cols      VARCHAR2(32767);
BEGIN
  SELECT LISTAGG('MAX(CASE WHEN rn = '||rn||' THEN State_Assign END) AS sa'||rn ,',') 
          WITHIN GROUP (ORDER BY 0)        
    INTO v_cols
    FROM (SELECT DISTINCT ROW_NUMBER() OVER (PARTITION BY id ORDER BY id) AS rn 
            FROM sampledata);

  v_sql :='SELECT id,
                  '|| v_cols ||',
                  COUNT(*) AS total
             FROM (SELECT s.*, ROW_NUMBER() OVER (PARTITION BY id ORDER BY 0) AS rn 
                     FROM sampledata s)
            GROUP BY id 
            ORDER BY id';

  OPEN v_recordset FOR v_sql;
  DBMS_OUTPUT.PUT_LINE(v_sql);
  RETURN v_recordset;
END;
/

该函数可以从 SQL Developer 的控制台调用

SQL> DECLARE
    result SYS_REFCURSOR;
BEGIN
   :result := Get_Pivoted_States;
END;
/

SQL> PRINT result; 

【讨论】:

  • 非常感谢!它看起来很棒的解决方案。一个问题是我们如何在 select 语句中调用函数。我使用下面的代码它没有给出结果。谢谢 select Get_Pivoted_States() from dual;
  • 不客气@KotiRaavi。是的,当您使用当前的 select 语句时,您会得到一个游标,而不是逐行的记录。需要创建一个 type 以便使用语法 SELECT * FROM TABLE(...) 调用,如question 的答案,但在这种情况下需要单独描述每一列,这将破坏当前的动态方式.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-11-19
  • 2021-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-21
相关资源
最近更新 更多