【问题标题】:How to Use PL/SQL and Dynamic Dates for pivot - New post如何使用 PL/SQL 和动态日期进行数据透视 - 新帖子
【发布时间】:2018-12-15 22:14:36
【问题描述】:

我在下面模拟了一些测试数据。非常感谢您的意见。可以真正使用您的帮助来动态调整日期。我也在下面尝试了我的第一个 PLSQL 代码。它不太有效。你们能帮帮我吗?所以第一部分是获取动态日期。第二部分是使用变量存储日期进行旋转。你认为这是正确的方法吗?真的可以使用一些帮助谢谢你的时间

with t as (
select 27 test_number, 'NCO' src_sys_cd, 'CO' rgn_cd, 'P' clm_type_cd, '06-27-2018' date_without_time, 14 rec_cnt from dual
union all
select 27 test_number, 'NHI' src_sys_cd, 'HI' rgn_cd, 'P' clm_type_cd, '06-28-2018' date_without_time, 15 rec_cnt from dual
union all
select 27 test_number, 'NHI' src_sys_cd, 'HI' rgn_cd, 'P' clm_type_cd, '06-29-2018' date_without_time, 16 rec_cnt from dual
union all
select 27 test_number, 'NHI' src_sys_cd, 'HI' rgn_cd, 'P' clm_type_cd, '06-30-2018' date_without_time, 60 rec_cnt from dual
union all
select 27 test_number, 'NHI' src_sys_cd, 'HI' rgn_cd, 'I' clm_type_cd, '06-30-2018' date_without_time, 60 rec_cnt from dual
union all
select 27 test_number, 'NCO' src_sys_cd, 'CO' rgn_cd, 'P' clm_type_cd, '07-01-2018' date_without_time, 28 rec_cnt from dual
union all
select 27 test_number, 'NCO' src_sys_cd, 'CO' rgn_cd, 'P' clm_type_cd, '07-02-2018' date_without_time, 70 rec_cnt from dual
union all
select 27 test_number, 'NGA' src_sys_cd, 'GA' rgn_cd, 'P' clm_type_cd, '07-03-2018' date_without_time, 80 rec_cnt from dual
union all
select 27 test_number, 'NMA' src_sys_cd, 'MA' rgn_cd, 'P' clm_type_cd, '07-04-2018' date_without_time, 90 rec_cnt from dual
union all
select 27 test_number, 'NSC' src_sys_cd, 'SC' rgn_cd, 'P' clm_type_cd, '07-05-2018' date_without_time, 100 rec_cnt from dual
union all
select 27 test_number, 'NNC' src_sys_cd, 'NC' rgn_cd, 'P' clm_type_cd, '07-06-2018' date_without_time, 20 rec_cnt from dual
union all
select 27 test_number, 'NHI' src_sys_cd, 'HI' rgn_cd, 'P' clm_type_cd, '07-07-2018' date_without_time, 29 rec_cnt from dual
union all
select 27 test_number, 'NHI' src_sys_cd, 'HI' rgn_cd, 'I' clm_type_cd, '07-07-2018' date_without_time, 29 rec_cnt from dual
union all
select 27 test_number, 'NHI' src_sys_cd, 'HI' rgn_cd, 'P' clm_type_cd, '07-08-2018' date_without_time, 28 rec_cnt from dual
)

下面是目前硬编码的SQL:

WITH T AS
          (
            SELECT DISTINCT
              TEST_NUMBER,
              SRC_SYS_CD,
              RGN_CD,
              CLM_TYP_CD,
              TO_CHAR(INSRT_DTTM,'mm-dd-yyyy') AS DATE_WITHOUT_TIME,
              REC_CNT
            FROM result
            WHERE TRUNC(INSRT_DTTM)   >= TO_DATE('05-19-2018', 'MM-DD-YYYY')
            AND TRUNC(INSRT_DTTM) <= TO_DATE('05-25-2018', 'MM-DD-YYYY')
          )
        SELECT *
        FROM  T PIVOT 
          ( 
          SUM(REC_CNT)  -- need an aggregate function, since there is only one row, it should be fine
          FOR DATE_WITHOUT_TIME IN ('05-19-2018','05-20-2018','05-21-2018','05-22-2018','05-23-2018','05-24-2018','05-25-2018') )
        ORDER BY
          TEST_NUMBER,
          SRC_SYS_CD,
          RGN_CD,
          CLM_TYP_CD;

这工作正常。我想使用下面的日期函数来替换 FOR 子句中的硬编码日期。

SELECT TRUNC(sysdate, 'IW') + Level - (1+ TRUNC(sysdate, 'IW') - TRUNC(sysdate, 'IW'))
        FROM dual
        CONNECT BY level <= 8;

这给了我这样的结果:

        DATE_WITHOUT_TIME
        02-JUL-2018 00:00:00
        03-JUL-2018 00:00:00
        04-JUL-2018 00:00:00
        05-JUL-2018 00:00:00
        06-JUL-2018 00:00:00
        07-JUL-2018 00:00:00
        08-JUL-2018 00:00:00
        09-JUL-2018 00:00:00

我想用这个动态日期替换 FOR 子句中的硬编码日期,但我之前没有做过任何 PLSQL。以下是我的尝试,不太奏效。你能帮忙吗?谢谢

       DECLARE
  date_time clob ;
  sqlqry clob;
BEGIN  
SELECT DISTINCT 
--    LISTAGG('''' || DT || ''' AS ' || DT,',') WITHIN GROUP (
    LISTAGG('''' || DT || '''',',') WITHIN GROUP (
  ORDER BY DT)
  INTO DATE_TIME
  FROM
    (SELECT TRUNC(sysdate, 'IW') + Level - (1+ TRUNC(sysdate, 'IW') - TRUNC(sysdate, 'IW')) AS dt
    FROM dual
      CONNECT BY level <= 8 --great
    ) ;
sqlqry:='SELECT DISTINCT
      TEST_NUMBER,
      SRC_SYS_CD,
      RGN_CD,
      CLM_TYP_CD,
      TO_CHAR(trunc(INSRT_DTTM)) AS DATE_WITHOUT_TIME,
      REC_CNT
    FROM CDW_T.DATA_MONITORING_RESULT 
PIVOT 
  ( 
  SUM(REC_CNT)  
  FOR DATE_WITHOUT_TIME IN (@date_time)) 
ORDER BY
  TEST_NUMBER,
  SRC_SYS_CD,
  RGN_CD,
  CLM_TYP_CD'; 

execute immediate sqlqry;
end;

Error report -
ORA-00936: missing expression
ORA-06512: at line 33
00936. 00000 -  "missing expression"
*Cause:    
*Action:

【问题讨论】:

  • 请标记您的数据库,每个数据库的功能和语法都有所不同。
  • 谢谢,客户端是oracle SQL Developer。和 BANNER CON_ID Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production 0 PL/SQL Release 12.1.0.2.0 - Production 0 “CORE 12.1.0.2.0 Production” 0 TNS for Linux:版本 12.1.0.2.0 - 生产 0 NLSRTL 版本 12.1.0.2.0 - 生产 0
  • 虽然我添加到原始帖子中的代码还不能正常工作,但我今天开始学习 PL/SQL。我可能一次吃得太大了。期待得到大家的帮助。

标签: sql oracle dynamic plsql pivot


【解决方案1】:

您完成了所有艰苦的工作,并且非常接近终点。不放弃的好工作!发现,在 SQL 中,您无法在不了解所有列的情况下构建数据透视结构。它是如何工作的。让我好奇,真的不可能吗? PL/SQL 来救援!

在包中创建了一个过程,它以光标形式给出了结果。显示包体:

create or replace package body test_pck as

procedure get_cursor(p_cursor out sys_refcursor) is

  l_date_list varchar2(4000);
  l_sql varchar2(4000);

begin

  select
    listagg('''' || tmp.date_without_time || '''',',') 
    within group (
    order by tmp.date_without_time)
  into l_date_list
  from(
    select distinct 
      tmp1.date_without_time
    from
      CDW_T.DATA_MONITORING_RESULT) tmp;

  dbms_output.put_line('date_list: '||l_date_list);

  l_sql := '
    select 
      *
    from(
      select
        tmp1.rec_cnt,
        tmp1.date_without_time
      from
        CDW_T.DATA_MONITORING_RESULT tmp1)
    pivot(
      sum(rec_cnt)
      for date_without_time in ( ' || l_date_list || ' ))';

  open p_cursor
  for l_sql;

exception
  when others then
    dbms_output.put_line(sqlcode || ' - ' || sqlerrm);
end get_cursor;
end test_pck;

在测试模式下调用过程后(PL/SQL 特性):

begin
  -- Call the procedure
  test_pck.get_cursor(p_cursor => :p_cursor);
end;

输出是:

有帮助吗?

【讨论】:

  • 您好,感谢您的帮助。我无权在我们的服务器上创建任何对象。我们是业务分析师。 IT 拥有服务器。他们不想我们乱来。或者也许在我们的脑海中反过来。 :-) 但我仍然从代码中的内容中学习。谢谢。
  • @Hanna,很高兴为您提供帮助。还有另一种方法,如果您只需要分析数据(并且如果您擅长阅读 XML 结构) - 使用 pivot XML() 构造。这样您就可以在一条 SQL 语句中完成所有操作。例如,枢轴部分可以写成 - <..pivot xml for job in distinct from emp> 祝你好运!
猜你喜欢
  • 2017-11-12
  • 1970-01-01
  • 1970-01-01
  • 2011-05-10
  • 1970-01-01
  • 2013-05-15
  • 1970-01-01
  • 2019-01-02
  • 1970-01-01
相关资源
最近更新 更多