• Asktom Oracle:How to multiplex single row into multiple rows


    Hi Tom,

    First of all, thanks for your tremendous contribution to the Oracle Community in helping people like us solve day to day Oracle replated problems.

    I have a small problem. Here are the details:

    CREATE TABLE T
    (
    HS_ID NUMBER(20) PRIMARY KEY,
    HS_NM VARCHAR2(30 BYTE),
    HS_STRT_DT DATE,
    HS_END_DT DATE,
    HS_CLT_IND CHAR(1 BYTE)
    );

    Insert into TMS.T
       (HS_ID, HS_NM, HS_STRT_DT, HS_END_DT, HS_CLT_IND)
     Values
       (1, 'Alaska', TO_DATE('01/01/2004 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('12/31/2012 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 'N');
    Insert into TMS.T
       (HS_ID, HS_NM, HS_STRT_DT, HS_END_DT, HS_CLT_IND)
     Values
       (2, 'Alabama', TO_DATE('01/01/2003 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('12/31/2012 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 'Y');
    Insert into TMS.T
       (HS_ID, HS_NM, HS_STRT_DT, HS_END_DT, HS_CLT_IND)
     Values
       (3, 'Virginia', TO_DATE('01/01/2001 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('12/31/2004 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 'N');
    Insert into TMS.T
       (HS_ID, HS_NM, HS_STRT_DT, HS_END_DT, HS_CLT_IND)
     Values
       (4, 'Virginia', TO_DATE('01/01/2005 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('12/31/2012 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 'Y');
    COMMIT;
    Here is the business rule:

    For each row in table t, view should traslate it into multiple rows based on start, end date and current year (HS_STRT_DT , HS_END_DT).

    Taking example of row with id=1:
    strt_dt=01/01/2004
    end_dt=12/31/2012
    current_year=2007

    If current_year <= end_dt then the row should get translated into 4 rows, one for each year starting 2004 and ending at 2007.
    If current_year > end_dt then that particular row should have (year(end_dt)-strt_dt) rows, starting at year(strt_dt) and ending at year(strt_dt)


    Thanks in advance for your time and help.

    and we said...

    You might have to play around with some boundary value conditions - just to validate that the math is right - don't know your data like you know it, but here is the idea, I used 100 as the max year spread, you can adjust based on your needs

    ops$tkyte%ORA10GR2> select * from t;
    
         HS_ID HS_NM                          HS_STRT_D HS_END_DT H
    ---------- ------------------------------ --------- --------- -
             1 Alaska                         01-JAN-04 31-DEC-12 N
             2 Alabama                        01-JAN-03 31-DEC-12 Y
             3 Virginia                       01-JAN-01 31-DEC-04 Y
             4 Virginia                       01-JAN-05 31-DEC-12 N
    
    WITH data
         AS (    SELECT LEVEL - 1 l
                   FROM DUAL
             CONNECT BY LEVEL <= 100)
      SELECT hs_id,
             hs_nm,
             TO_CHAR (ADD_MONTHS (hs_strt_dt, l * 12), 'yyyy'),
             hs_clt_ind
        FROM t, data
       WHERE l <
                CEIL (MONTHS_BETWEEN (LEAST (SYSDATE, hs_end_dt), hs_strt_dt) / 12)
             AND TO_CHAR (ADD_MONTHS (hs_strt_dt, l * 12), 'yyyy') <=
                    TO_CHAR (SYSDATE, 'yyyy')
    ORDER BY 1, 2, 3 HS_ID HS_NM TO_C H ---------- ------------------------------ ---- - 1 Alaska 2004 N 1 Alaska 2005 N 1 Alaska 2006 N 1 Alaska 2007 N 2 Alabama 2003 Y 2 Alabama 2004 Y 2 Alabama 2005 Y 2 Alabama 2006 Y 2 Alabama 2007 Y 3 Virginia 2001 Y 3 Virginia 2002 Y 3 Virginia 2003 Y 3 Virginia 2004 Y 4 Virginia 2005 N 4 Virginia 2006 N 4 Virginia 2007 N 16 rows selected.
  • 相关阅读:
    【Gstreamer开发】TI嵌入式处理器GStreamer pipeline
    【Gstreamer开发】TI嵌入式处理器GStreamer pipeline
    【ARM-LInux开发】利用scp 远程上传下载文件/文件夹
    【ARM-LInux开发】利用scp 远程上传下载文件/文件夹
    【VS开发】ClientToScreen 和ScreenToClient 用法
    【VS开发】ClientToScreen 和ScreenToClient 用法
    【C/C++开发】C中调用C++函数
    【C/C++开发】C中调用C++函数
    【C/C++开发】字符串操作
    【C/C++开发】字符串操作
  • 原文地址:https://www.cnblogs.com/tracy/p/2134496.html
Copyright © 2020-2023  润新知