【问题标题】:Pivotting on oracle v10.2.0 with two dynamic values使用两个动态值在 oracle v10.2.0 上进行透视
【发布时间】:2020-03-26 08:28:57
【问题描述】:

我需要得到这样的查询结果:

        |Person1                  |Person2                  |Person3                  |...
        ------------------------------------------------------------------------------------
Date1   |function(Person1Id,Date1)|function(Person2Id,Date1)|function(Person3Id,Date1)|...         
Date2   |function(Person1Id,Date2)|function(Person2Id,Date2)|function(Person3Id,Date2)|...
Date3   |function(Person1Id,Date3)|function(Person2Id,Date3)|function(Person3Id,Date3)|...
.
.
.

日期来自用户,PersonIds 来自表。我需要做的只是发送函数的 id 和日期并得到它的结果。由于我正在研究 oracle v10.2.0,因此旋转不起作用并编写案例...当每个人的陈述都不起作用时,因为我要获取的表中有很多人。

任何帮助表示赞赏。

【问题讨论】:

    标签: oracle plsql pivot oracle10g dynamic-pivot


    【解决方案1】:

    您可以在 DB 版本10g 中使用条件聚合,例如

    SELECT myDate,
           MAX(CASE WHEN PersonId=1 THEN myfunc(PersonId,myDate) END) AS Person1,
           MAX(CASE WHEN PersonId=2 THEN myfunc(PersonId,myDate) END) AS Person2,
           MAX(CASE WHEN PersonId=3 THEN myfunc(PersonId,myDate) END) AS Person3
      FROM t 
     GROUP BY myDate
    

    更新: 但是,即使在 DB 10g 中,也有一个选项可以使用 SYS_REFCURSOR 进行动态旋转,例如。使用 PL/SQL 而不是仅使用 SQL,如果您使用的是 SQL Developer,则在命令行上显示结果集。创建存储函数

    CREATE OR REPLACE FUNCTION get_person_rs RETURN SYS_REFCURSOR IS
      v_recordset SYS_REFCURSOR;
      v_sql       VARCHAR2(32767);
      v_str       VARCHAR2(32767);
    BEGIN
      WITH tt AS
      ( 
       SELECT PersonId, 
              ROW_NUMBER() OVER (ORDER BY PersonId) AS rn  
         FROM t 
        GROUP BY PersonId 
      )
      SELECT TO_CHAR(RTRIM(XMLAGG(XMLELEMENT(e, 
               'MAX(CASE WHEN PersonId = '||PersonId||
                       ' THEN myfunc(PersonId,myDate) 
                          END) AS Person'||rn         
               , ',')).EXTRACT('//text()').GETCLOBVAL(), ','))
        INTO v_str         
        FROM tt;  
    
      v_sql :=
      'SELECT myDate, '|| v_str ||'
         FROM t
        GROUP BY myDate';
    
      OPEN v_recordset FOR v_sql;
      RETURN v_recordset;
    END;
    

    其中,ROW_NUMBER()使用了10g提供的解析函数,但10g还没有LISTAGG()字符串聚合函数。所以使用XMLAGG 代替。函数中生成的这个 SQL 字符串也与上面的完全相同,例如。在条件聚合逻辑中。

    然后运行以下代码:

    VAR rc REFCURSOR
    EXEC :rc := get_person_rs;
    PRINT rc
    

    从 SQL Developer 的命令行中查看由当前现有数据动态生成的预期结果集。

    【讨论】:

    • 巴巴罗斯,非常感谢您的时间和帮助。但是,人数会超过300,这种情况下,我会为每个人写case,对吧?如果是,我需要为每个人动态编写,你知道有什么解决方案吗?
    • 不客气,兄弟。这是不可能通过 sql 实现的,但可能是 PL/SQL,实际上您最初通过使用 dynamic queries 标记了 plsql,但似乎仍然是一个令人生畏的问题 :) @ilhank。
    • 除了two dimensional arrays 将与PL/SQL 代码@ilhank 一起使用。
    • 非常感谢Barbaros,我将首先使用动态查询。让我们看看会发生什么。
    猜你喜欢
    • 1970-01-01
    • 2013-05-15
    • 1970-01-01
    • 2019-08-31
    • 1970-01-01
    • 1970-01-01
    • 2019-01-02
    • 2018-04-01
    • 1970-01-01
    相关资源
    最近更新 更多