在 Oracle Pivot 中的 IN 条件下使用子查询

Posted

技术标签:

【中文标题】在 Oracle Pivot 中的 IN 条件下使用子查询【英文标题】:Using subquery at IN codition in Oracle Pivot 【发布时间】:2019-09-22 10:45:33 【问题描述】:

如果我事先不知道列名 C0 的值是什么, 如何修改我的 IN 条件?

如果我使用“IN ('a' AS A, 'b' AS B)”,它的工作原理如下。

ROWNUM   M  A  B
------  -- -- --
1     a__  3.5 35
2     abd  1.5 15
3     abe  3.5 35
4     ace  5.5 55

但是,如果我使用子查询“IN (SELECT DISTINCT C FROM DATAA)”,就会出现 ORA-00936 错误。

我的代码如下;

--Table and data
    CREATE TABLE T4 (
    C0 VARCHAR2(10),
    C1 VARCHAR2(10),
    C2 NUMBER
    );
    INSERT INTO T4  VALUES ('a','abd',1);
    INSERT INTO T4  VALUES ('a','abd',2);
    INSERT INTO T4  VALUES ('a','abe',3);
    INSERT INTO T4  VALUES ('a','abe',4);
    INSERT INTO T4  VALUES ('a','ace',5);
    INSERT INTO T4  VALUES ('a','ace',6);

    INSERT INTO T4  VALUES ('b','abd',10);
    INSERT INTO T4  VALUES ('b','abd',20);
    INSERT INTO T4  VALUES ('b','abe',30);
    INSERT INTO T4  VALUES ('b','abe',40);
    INSERT INTO T4  VALUES ('b','ace',50);
    INSERT INTO T4  VALUES ('b','ace',60);  


--Code
        WITH DATAA AS (
        SELECT ROWNUM,rr.C0,rr.M, rr.ss
        FROM
        (
        SELECT C0,C1 M, AVG(C2) ss FROM T4  GROUP BY C0, C1
        UNION
        SELECT C0,SUBSTR(C1,1,1)||'__'  ,AVG(C2) ss FROM T4  GROUP BY C0,SUBSTR(C1,1,1) ) rr
        )
        -- USING PIVOT
        SELECT
            ROWNUM,
            TAB.*
        FROM
            (
                SELECT
                    *
                FROM
                    (
                        SELECT
                            M,
                            C0,
                            SS
                        FROM
                            DATAA
                    ) PIVOT (
                        SUM ( SS )
                        FOR ( C0 )              
                        IN ( 'a' AS A, 'b' AS B )   -- This condition works correctly, as expected
           --IN ( SELECT DISTINCT C FROM DATAA)  -- But,this subquery does not work. ORA-00936 error shows.
                    )
                ORDER BY
                    1
            ) TAB;

【问题讨论】:

因为在 Oracle 的 SQL 中数据透视不是动态的,@Lukasz Szozda 提到的 XML 选项除外。 【参考方案1】:

您正在搜索动态 PIVOT。一种方法是使用PIVOT XML:

将 XML 关键字添加到 PIVOT 运算符允许我们将生成的数据透视结果转换为 XML 格式。 它还使 PIVOT 更加灵活,允许我们用子查询或 ANY 通配符替换硬编码的 IN 子句。

SELECT *
FROM (SELECT M, C0, SS FROM DATAA) 
PIVOT XML (SUM(SS) FOR (C0) IN (SELECT DISTINCT C FROM DATAA))

【讨论】:

以上是关于在 Oracle Pivot 中的 IN 条件下使用子查询的主要内容,如果未能解决你的问题,请参考以下文章

带有条件的 Oracle SQL Pivot 将行转换为列

oracle行转列实践

Oracle Pivot简单用法

oracle行专列

oracle行专列

PIVOT在SQL Sever里面和Oracle里面的用法区别