복붙노트

[SQL] 오라클 SQL : 실종 날짜를 기입

SQL

오라클 SQL : 실종 날짜를 기입

나는 삼십 일 동안 나에게 생산 날짜와 생산 볼륨을 제공하는 다음과 같은 코드가 있습니다.

select 
(case when trunc(so.revised_due_date) <= trunc(sysdate) 
    then trunc(sysdate) else trunc(so.revised_due_date) end) due_date, 
(case 
    when (case when sp.pr_typ in ('VV','VD') then 'DVD' when sp.pr_typ in ('RD','CD') 
    then 'CD' end) = 'CD' 
    and  (case when so.tec_criteria in ('PI','MC') 
    then 'XX' else so.tec_criteria end) = 'OF'
    then sum(so.revised_qty_due)
end) CD_OF_VOLUME
from shop_order so
left join scm_prodtyp sp
on so.prodtyp = sp.prodtyp
where so.order_type = 'MD' 
and so.plant = 'W' 
and so.status_code between '4' and '8' 
and trunc(so.revised_due_date) <= trunc(sysdate)+30
group by trunc(so.revised_due_date), so.tec_criteria, sp.pr_typ
order by trunc(so.revised_due_date)

내가 가진 문제는 계획된 생산 날짜가있는 경우, 날짜가 보고서에 표시 실 거예요입니다. 누락 된 날짜에 채우는 방법이 있나요.

즉 현재 보고서 쇼 다음 ...

DUE_DATE    CD_OF_VOLUME 
14/04/2015     35,267.00 
15/04/2015     71,744.00 
16/04/2015     20,268.00 
17/04/2015     35,156.00 
18/04/2015     74,395.00 
19/04/2015      3,636.00 
21/04/2015      5,522.00
22/04/2015     15,502.00
04/05/2015     10,082.00

참고 : 실종 날짜 (20/04/2015, 2015년 3월 5일에 23/04/2015)

범위 SYSDATE에서 삼십일 동안 항상. 어떻게 누락 된 날짜를 기입합니까? 당신은 달력 테이블의 어떤 종류가 필요하십니까?

감사

해결법

  1. ==============================

    1.다음과 같이 SYSDATE로부터 30 일의 기간을 얻을 수 있습니다 (난 당신이 SYSDATE를 포함 할 것 같은데요?) :

    다음과 같이 SYSDATE로부터 30 일의 기간을 얻을 수 있습니다 (난 당신이 SYSDATE를 포함 할 것 같은데요?) :

    WITH mydates AS (
        SELECT TRUNC(SYSDATE) - 1 + LEVEL AS due_date FROM dual
       CONNECT BY LEVEL <= 31
    )
    

    (뿐만 아니라 CTE에 검색어를 넣어 아마도 나쁜 생각을하지 않음) 그런 다음 왼쪽을 할 수 위의를 사용하여 쿼리에 가입 :

    WITH mydates AS (
        SELECT TRUNC(SYSDATE) - 1 + LEVEL AS due_date FROM dual
       CONNECT BY LEVEL <= 31
    ), myorders AS (
        select 
        (case when trunc(so.revised_due_date) <= trunc(sysdate) 
            then trunc(sysdate) else trunc(so.revised_due_date) end) due_date, 
        (case 
            when (case when sp.pr_typ in ('VV','VD') then 'DVD' when sp.pr_typ in ('RD','CD') 
            then 'CD' end) = 'CD' 
            and  (case when so.tec_criteria in ('PI','MC') 
            then 'XX' else so.tec_criteria end) = 'OF'
            then sum(so.revised_qty_due)
        end) CD_OF_VOLUME
        from shop_order so
        left join scm_prodtyp sp
        on so.prodtyp = sp.prodtyp
        where so.order_type = 'MD' 
        and so.plant = 'W' 
        and so.status_code between '4' and '8' 
        and trunc(so.revised_due_date) <= trunc(sysdate)+30
        group by trunc(so.revised_due_date), so.tec_criteria, sp.pr_typ
        order by trunc(so.revised_due_date)
    )
    SELECT mydates.due_date, myorders.cd_of_volume
      FROM mydates LEFT JOIN myorders
        ON mydates.due_date = myorders.due_date;
    

    당신은 대신에 NULL의 "실종"날짜, cd_of_volume 위 AS 사용 COALESCE (myorders.cd_of_volume, 0)에 0을 표시 할 경우.

  2. ==============================

    2.당신이 할 수있는 일은 이것이다 : 당신이 필요로하는 모든 일에 새로운 테이블을 생성.

    당신이 할 수있는 일은 이것이다 : 당신이 필요로하는 모든 일에 새로운 테이블을 생성.

    WITH DAYS AS
    (SELECT TRUNC(SYSDATE) - ROWNUM DDD
     FROM ALL_OBJECTS
     WHERE ROWNUM < 365)
    SELECT
      DAYS.DDD
    FROM
    
      DAYS;
    

    다음 완전 외부는 thoes 테이블 사이에 조인

    select  DUE_DATE ,   CD_OF_VOLUME , DDD
    from (
        select 
        (case when trunc(so.revised_due_date) <= trunc(sysdate) 
            then trunc(sysdate) else trunc(so.revised_due_date) end) due_date, 
        (case 
            when (case when sp.pr_typ in ('VV','VD') then 'DVD' when sp.pr_typ in ('RD','CD') 
            then 'CD' end) = 'CD' 
            and  (case when so.tec_criteria in ('PI','MC') 
            then 'XX' else so.tec_criteria end) = 'OF'
            then sum(so.revised_qty_due)
        end) CD_OF_VOLUME
        from shop_order so
        left join scm_prodtyp sp
        on so.prodtyp = sp.prodtyp
        where so.order_type = 'MD' 
        and so.plant = 'W' 
        and so.status_code between '4' and '8' 
        and trunc(so.revised_due_date) <= trunc(sysdate)+30
        group by trunc(so.revised_due_date), so.tec_criteria, sp.pr_typ
        order by trunc(so.revised_due_date)
    )  full outer join   NEW_TABLE new on (    new .DDD =  DUE_DATE     )
      where new .DDD between   /* */   AND   /* */   /*   pick your own limit) */
    
  3. ==============================

    3.당신은에 의해 왼쪽 연결을 사용하여 간격을 얻을 수 있습니다 조인

    당신은에 의해 왼쪽 연결을 사용하여 간격을 얻을 수 있습니다 조인

    스키마입니다 가정 :

    create table tbl(DUE_DATE date, CD_OF_VOLUME float);
    insert into tbl values(to_date('14/04/2015','DD/MM/YYYY'),35267.00);
    insert into tbl values(to_date('15/04/2015','DD/MM/YYYY'),71744.00); 
    insert into tbl values(to_date('16/04/2015','DD/MM/YYYY'),20268.00); 
    insert into tbl values(to_date('17/04/2015','DD/MM/YYYY'),35156.00); 
    insert into tbl values(to_date('18/04/2015','DD/MM/YYYY'),74395.00); 
    insert into tbl values(to_date('19/04/2015','DD/MM/YYYY'),3636.00); 
    insert into tbl values(to_date('21/04/2015','DD/MM/YYYY'),5522.00);
    insert into tbl values(to_date('22/04/2015','DD/MM/YYYY'),15502.00);
    insert into tbl values(to_date('04/05/2015','DD/MM/YYYY'),10082.00);
    

    당신은 말할 수있다 :

    with cte as
    (
      select (select min(DUE_DATE)-1 from tbl)+ level as dt
      from dual
      connect by level <= (select max(DUE_DATE)-min(DUE_DATE) from tbl)
    )
    select to_char(c.dt,'DD/MM/YYYY') gap,null volume 
    from cte c
    left join tbl t on c.dt=t.DUE_DATE
    where t.DUE_DATE is null
    order by c.dt
    

    결과:

    GAP         VOLUME
    20/04/2015  (null)
    23/04/2015  (null)
    24/04/2015  (null)
    25/04/2015  (null)
    26/04/2015  (null)
    27/04/2015  (null)
    28/04/2015  (null)
    29/04/2015  (null)
    30/04/2015  (null)
    01/05/2015  (null)
    02/05/2015  (null)
    03/05/2015  (null)
    

    주의 사항 : 원래 쿼리에서이를 구현할 수있는 하나의 간단한 방법은 쿼리를 감싸고 위의 코드에서 하위 쿼리 대신 TBL로 사용하는 것입니다.

  4. from https://stackoverflow.com/questions/29634180/oracle-sql-fill-in-missing-dates by cc-by-sa and MIT license