zoukankan      html  css  js  c++  java
  • 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.
  • 相关阅读:
    vue.js---利用vue cli脚手架工具+webpack创建项目遇到的坑
    List<KeyValuePair<TKey,TValue>> 与 Dictionary<TKey,TValue> 不同
    StackExchange.Redis 官方文档(一) Basics
    离线安装chrome插件
    Cocoapods的安装与使用
    多线程
    作业二:个人编程项目——编写一个能自动生成小学四则运算题目的程序
    初学者如何在博客园发布博客
    作业一:建立博客、自我介绍、速读教材、学习进度总结
    计科131同学们的博客
  • 原文地址:https://www.cnblogs.com/tracy/p/2134496.html
Copyright © 2011-2022 走看看