【问题标题】:PIVOT for value by reported date in Oracle SQL在 Oracle SQL 中按报告日期的 PIVOT 值
【发布时间】:2021-04-22 18:17:54
【问题描述】:

我正在尝试使用 pivot 来完成以下操作:

源表中的数据如下:

Company Company ID Product Code Product Unit Reporting Year Value
a 1 dd gln 2019 7
a 1 dd gln 2020 2
b 2 bb kg 2021 3

透视表中的数据应如下所示:

Company Company ID Product Code Product Unit 2019 2020 2021
a 1 dd gln 7 2
b 2 bb kg 3

我试过了,还是不行:

从源中选择 * 枢 ( 年份的最大值(值) (2019,2020,2021) );

非常感谢任何帮助。

【问题讨论】:

  • edit 包含minimal reproducible example 的问题:source 表的 DDL (CREATE TABLE) 语句;示例数据的 DML (INSERT) 语句;以及错误的全文。表中列名为Reporting Year 的标题与查询为year 之间存在不匹配;其中一个是错误的,我们需要知道您如何创建表格以提供准确的解决方案。最简单的答案是您有一个错字并且使用了错误的名称,但只是说“我试过了,但它没有用”无助于调试它,我们需要更多信息。

标签: sql oracle pivot


【解决方案1】:

year 更改为reportingyear,您的代码似乎可以工作:

select * from source pivot ( max(value) for reportingyear in (2019,2020,2021) );

其中,对于样本数据:

CREATE TABLE source ( Company, CompanyID, ProductCode, ProductUnit, ReportingYear, Value ) AS
SELECT 'a', 1, 'dd', 'gln', 2019, 7 FROM DUAL UNION ALL
SELECT 'a', 1, 'dd', 'gln', 2020, 2 FROM DUAL UNION ALL
SELECT 'b', 2, 'bb', 'kg', 2021, 3 FROM DUAL

输出:

COMPANY COMPANYID PRODUCTCODE PRODUCTUNIT 2019 2020 2021
b 2 bb kg <null> <null> 3
a 1 dd gln 7 2 <null>

如果您使用带引号的标识符并且列名中有空格,那么每次引用该列时都需要使用带引号的标识符:

select * from source pivot ( max(value) for "Reporting Year" in (2019,2020,2021) );

db小提琴here

【讨论】:

    【解决方案2】:

    只使用条件聚合:

    select Company, Company_ID, Product_Code, Product_Unit,
           sum(case when year = 2019 then value else 0 end) as val_2019,
           sum(case when year = 2020 then value else 0 end) as val_2020,
           sum(case when year = 2021 then value else 0 end) as val_2021
    from source
    group by Company, Company_ID, Product_Code, Product_Unit;
    

    【讨论】:

      【解决方案3】:

      无需使用动态代码结构指定PIVOT 子句列表中的所有年份,假设当前表中只有这三个年份值,并传播到新的透视列以及新插入的即将到来的年份值通过创建一个存储函数,例如

      CREATE OR REPLACE FUNCTION Fn_Pivot_Table RETURN SYS_REFCURSOR IS
        v_recordset SYS_REFCURSOR;
        v_sql       VARCHAR2(32767);
        v_cols      VARCHAR2(32767);   
      BEGIN
        SELECT LISTAGG( ReportingYear  , ',') WITHIN GROUP ( ORDER BY ReportingYear )                 
          INTO v_cols
          FROM ( SELECT DISTINCT ReportingYear FROM source );
            
        v_sql :='SELECT * 
                   FROM source
                  PIVOT(
                         MAX(Value) FOR ReportingYear IN (' || v_cols ||' ) 
                        ) 
                  ORDER BY CompanyID';
      
        OPEN v_recordset FOR v_sql;
        RETURN v_recordset;
      END;
      /
      

      可以从 SQL Developer 的控制台调用

      SQL> DECLARE
          result SYS_REFCURSOR;
      BEGIN
         :result := Fn_Pivot_Table;
      END;
      /
      
      SQL> PRINT result;
      

      【讨论】:

        【解决方案4】:

        你快到了:

        select * from source pivot ( max(Value) for "Reporting Year" in (2019,2020,2021) );
        

        请注意,Oracle 不允许列名带有空格,因此应该将其中的空格替换为下划线,例如。

        因此,查询将是:

        select * from source pivot ( max(Value) for "Reporting_Year" in (2019,2020,2021) );
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-09-29
          • 2021-09-04
          • 1970-01-01
          • 1970-01-01
          • 2012-12-23
          相关资源
          最近更新 更多