2013-08-29 251 views
0

Oracle 11i - 查找將創建一組日期範圍的查詢,以使CUSTOM值覆蓋STANDARD值,並將STANDARD值保留在未被覆蓋的位置。將SQL查詢覆蓋日期範圍

STANDARD 
CUSTOMER_ID START_DATE END_DATE  VALUE 
0001   02/01/2013 09/15/2013 10 

CUSTOM 
CUSTOMER_ID START_DATE END_DATE  VALUE 
0001   01/15/2013 03/15/2013 20 
0001   07/01/2013 07/31/2013 30 

Desired Result 
CUSTOMER_ID START_DATE END_DATE  VALUE 
0001   02/01/2103 03/15/2013 20 
0001   03/16/2013 06/30/2013 10 
0001   07/01/2013 07/31/2013 30 
0001   08/01/2013 09/15/2013 10 

這裏是試運行的結果:

select sc.customer_id, sc.thedate as start_date, 
     lead(**sc.thedate**) over (partition by sc.customer_id order by sc.thedate) as end_date, 
     sc.value 
from (select customer_id, start_date as thedate, value 
     from standard 
     union all 
     select customer_id, start_date, value 
     from custom 
     union all 
     select s.customer_id, c.end_date + 1, s.value 
     from custom c join 
      standard s 
      on c.customer_id = s.customer_id 
     union all 
     select customer_id, end_date, NULL 
     from standard 
    ) sc 
where value is not NULL; 

CUSTOMER_ID  START_DATE    END_DATE    VALUE 
0001   15-JAN-13 12.00.00 AM 01-FEB-13 12.00.00 AM 20 
0001   01-FEB-13 12.00.00 AM 16-MAR-13 12.00.00 AM 10 
0001   16-MAR-13 12.00.00 AM 01-JUL-13 12.00.00 AM 10 
0001   01-JUL-13 12.00.00 AM 01-AUG-13 12.00.00 AM 30 
0001   01-AUG-13 12.00.00 AM       10 

回答

0

這是一種方法。將數據分解爲每個日期(每個客戶)的值開始時的數據。然後使用Oracle分析函數將數據放在一起。日期是「價值」的開始。然後使用lead()獲取下一個日期。

select sc.customer_id, sc.thedate as start_date, 
     lead(sc.start_date) over (partition by sc.customer_id order by sc.thedate) as end_date, 
     sc.value 
from (select s.customer_id, s.start_date as thedate, s.value 
     from standard 
     union all 
     select c.customer_id, c.start_date, c.value 
     from custom 
     union all 
     select s.customer_id, c.end_date + 1, s.value 
     from custom c join 
      standard s 
      on c.customer_id = s.customer_id 
     union all 
     select s.customer_id, s.end_date, NULL 
     from standard 
    ) sc 
where value is not NULL; 

請注意,這包括爲end_date一個額外的記錄,你不需要爲最後一行。這被標記爲NULL值,該值在外部查詢中被過濾掉。

+0

謝謝,我會研究這個解決方案和亞馬遜的SQL/Excel書籍。看起來它在六年左右後仍然得到很好的評價。任何推薦的補充劑? – nullsetup

+0

向@Gordon提問時添加了修改和結果 – nullsetup