2014-10-10 54 views
0

我有一個表ENCOUNTERS在Oracle 11g數據庫,樣本的醫療數據,SQL自子查詢改進

ID DC_DATE CPI 
1 "1/1/2012" a 
2 "1/2/2012" b 
3 "1/3/2012" c 
4 "1/4/2012" d 
5 "2/2/2012" a 
6 "2/1/2012" b 
7 "2/3/2012" e 
8 "2/4/2012" f 
9 "2/5/2012" g 
10 "2/29/2012" a 

ID是一個人的唯一的訪問標識符和CPI是當人們前來參觀,跟蹤一個人ID我們再次在以後的日子。

我的任務是創建一個查詢,返回所有這些列加上三個新列,PREVIOUS_ID, PREVIOUS_DC_DATE, and READMIT_DAYS Readmit_Days是新訪問DC_Date和之前訪問DC_Date之間的天數差。

目前我必須運行以下代碼才能獲取我需要的數據。

SELECT a.ID, 
     a.DC_DATE, 
     a.CPI, 
     (SELECT MAX(b.ID) 
     FROM ENCOUNTERS b 
     WHERE a.CPI = b.CPI 
       AND a.ID > b.ID)        AS Previous_ID, 
     (SELECT MAX(b.DC_DATE) 
     FROM ENCOUNTERS b 
     WHERE a.CPI = b.CPI 
       AND a.DC_DATE > b.DC_DATE)     AS Previous_DC_Date, 
     (a.DC_DATE - ((SELECT MAX(b.DC_DATE) 
         FROM ENCOUNTERS b 
         WHERE a.CPI = b.CPI 
           AND a.DC_DATE > b.DC_DATE))) AS ReAdmit_Days 
FROM ENCOUNTERS a; 

現在這個工作,但它看起來方式太複雜了。有沒有更好的方法來獲得我所需要的?

這就是我運行時得到的結果,這是正確的。只是尋求建議。

ID DC_DATE CPI Previous_ID Previous_DC_Date Readmit_Days 
1 "1/1/2012" a   
2 "1/2/2012" b   
3 "1/3/2012" c   
4 "1/4/2012" d   
5 "2/2/2012" a 1 "1/1/2012" 32 
6 "2/1/2012" b 2 "1/2/2012" 30 
7 "2/3/2012" e   
8 "2/4/2012" f   
9 "2/5/2012" g   
10 "2/29/2012" a 5 "2/2/2012" 27 

回答

1
with encounters as (
select 1 id, to_date('01/01/2012', 'MM/DD/YYYY') dc_date, 'a' cpi from dual union all 
select 2, to_date('01/02/2012', 'MM/DD/YYYY'), 'b' from dual union all 
select 3, to_date('01/03/2012', 'MM/DD/YYYY'), 'c' from dual union all 
select 4, to_date('01/04/2012', 'MM/DD/YYYY'), 'd' from dual union all 
select 5, to_date('02/02/2012', 'MM/DD/YYYY'), 'a' from dual union all 
select 6, to_date('02/01/2012', 'MM/DD/YYYY'), 'b' from dual union all 
select 7, to_date('02/03/2012', 'MM/DD/YYYY'), 'e' from dual union all 
select 8, to_date('02/04/2012', 'MM/DD/YYYY'), 'f' from dual union all 
select 9, to_date('02/05/2012', 'MM/DD/YYYY'), 'g' from dual union all 
select 10, to_date('02/29/2012', 'MM/DD/YYYY'), 'a' from dual) 
select id, dc_date, cpi, previous_id, previous_dc_date, dc_date - previous_dc_date readmit_days 
from 
(select id, dc_date, cpi, 
     max(id) over (partition by cpi order by id range between unbounded preceding and 1 preceding) as previous_id, 
     max(dc_date) over (partition by cpi order by dc_date rows between unbounded preceding and 1 preceding) as previous_dc_date 
    from encounters); 

分析功能在這裏更好。在你的查詢中,你做了很多額外的相關查詢。

P.S.第二個窗口(使用dc_date和「行」窗口)將無法正確使用關係。您可以在這裏使用「範圍」和時間間隔。這只是一個例子。

+0

非常有趣。我會研究你使用的關鍵字。我從來沒有用過和分區。我仍然試圖圍繞這個如何工作。謝謝 – Scheballs 2014-10-13 03:09:09