2012-08-14 55 views
1

讓我們假設我有含有下列獲取最新的數據爲每個字段從一個表中的Oracle

  • VISIT_DATE(時間戳)的表中調用VISITS
  • HEIGHT(NUMBER)
  • 腰圍(NUMBER)
  • 量(數)
  • PATIENT_ID(NUMBER)

    VISIT_DATE | HEIGHT | WAIST |重量| PATIENT_ID

    10/01/2012 | (空)        | 96         | 130 | 44123

    11/01/2012 | 1.74             | (null)    | 120 | 44123

    12/01/2012 | (空)          | (null)  | 150 | 44123

我需要的是一個SQL SELECT語句來獲得每個列中的最新值,但忽略了空字段,所以我需要的輸出將

WHERE子句將

WHERE PATIENT_ID = 44123 ORDER BY VISIT_DATE DESC LIMIT 1 

12/01/2012 | 1.74 | 96 | 150 | 44123 

正如你可以從輸出看到我期望從選擇讓我後退操作通過EA爲病人排序,直到我找到每個字段的值。

我希望這個問題是明確的,可能的,我已經搜索,但至今沒有找到任何真正的解決方案,這將用於簡化與醫院一起使用的醫療系統,並且有大約100個字段以上只是幾個領域的一個例子,讓我們能夠理解所需的概念。

+3

這不是一個好的設計,它會很難保持!如果你想保存歷史記錄 - 在另一張桌子上做,但每個病人只保留一個記錄(並分別更新) - 這會讓你的生活變得更輕鬆! – alfasin 2012-08-14 05:25:18

回答

3
create table VISITS 
(
    VISIT_DATE TIMESTAMP 
, HEIGHT NUMBER 
, WAIST NUMBER 
, WEIGHT NUMBER 
, PATIENT_ID NUMBER 
); 


insert into visits values(systimestamp, null, 96, 130, 44123); 
insert into visits values(systimestamp, 1.74, NULL, 120, 44123); 
insert into visits values(systimestamp, null, NULL, 150, 44123); 




select 
    last_visit_date 
, height 
, waist 
, weight 
, patient_id 
from 
(
    select 
    first_value(VISIT_DATE) over(partition by patient_id order by visit_date desc) last_visit_date 
    , first_value(HEIGHT ignore nulls) over(partition by patient_id order by visit_date desc) height 
    , first_value(WAIST ignore nulls) over(partition by patient_id order by visit_date desc) WAIST 
    , first_value(WEIGHT ignore nulls) over(partition by patient_id order by visit_date desc) WEIGHT 
    , min(visit_date) over(partition by patient_id) min_visit_date 
    , visit_date 
    , patient_id 
    from visits 

) 
where 
    min_visit_date = visit_date 
and patient_id = 44123 
; 

下面是SQLfiddle example

+0

哇你完美的絕對明星非常感謝你 – cghrmauritius 2012-08-14 14:50:26

1

試試這個:

select a.PATIENT_ID,a.VISIT_DATE,b.HEIGHT,c.WEIGHT,d.WAIST 
from 
    (select PATIENT_ID, 
       max(VISIT_DATE) as VISIT_DATE 
    from  VISITS 
    group by PATIENT_ID)a 
join 
    (select PATIENT_ID,HEIGHT from (select PATIENT_ID,HEIGHT 
    from VISITS v 
    order by case when v.HEIGHT is null 
     then to_date('1900/01/01','YYYY/MM/DD') 
        else v.VISIT_DATE end desc) where rownum=1)b 
on a.PATIENT_ID=b.PATIENT_ID 
join 
    (select PATIENT_ID,WEIGHT from (select PATIENT_ID,WEIGHT 
    from VISITS v 
    order by case when v.WEIGHT is null 
      then to_date('1900/01/01','YYYY/MM/DD') 
         else v.VISIT_DATE end desc) where rownum=1)c 
on a.PATIENT_ID=c.PATIENT_ID 
join 
    (select PATIENT_ID,WAIST from (select PATIENT_ID,WAIST 
    from VISITS v 
    order by case when v.WAIST is null 
      then to_date('1900/01/01','YYYY/MM/DD') 
         else v.VISIT_DATE end desc) where rownum=1)d 
on a.PATIENT_ID=d.PATIENT_ID   

SQL小提琴Demo

+0

我猜這個查詢輸出正確的結果,只有當患者總是體重增加:) – valex 2012-08-14 06:20:32

+0

@valexhome:我已經更新了我的查詢.. plz現在檢查它 – 2012-08-14 06:58:26

+0

在oracle中,ROWNUM被賦值BEFORE order by this conditions(ROWNUM = 1)in your子查詢沒有意義。要在oracle中獲得TOP 1,你應該使用select和nested子查詢。 [這裏是Oracle常見問題解答:如何選擇TOP N](http://www.orafaq.com/faq/how_does_one_select_the_top_n_rows_from_a_table) – valex 2012-08-14 07:11:12

1
select visits2.patient_id,visits2.maxDate, 
( select max(HEIGHT) from visits where visit_Date= 
    (select max(visit_date) m from visits l 
    where (HEIGHT is not null) 
      and 
      (l.patient_id=visits2.patient_id) 
    ) 
    and 
    (patient_id=visits2.patient_id) 
) HEIGHT, 

( select max(WAIST) from visits where visit_Date= 
    (select max(visit_date) m from visits l 
    where (WAIST is not null) 
      and 
      (l.patient_id=visits2.patient_id) 
    ) 
    and 
    (patient_id=visits2.patient_id) 
) WAIST, 
( select max(WEIGHT) from visits where visit_Date= 
    (select max(visit_date) m from visits l 
    where (WEIGHT is not null) 
      and 
      (l.patient_id=visits2.patient_id) 
    ) 
    and 
    (patient_id=visits2.patient_id) 
) WEIGHT 


from 
(select patient_id,max(visit_date) maxDate 
from visits group by patient_id) visits2 

這裏是SQLfiddle example

+1

如果2個不同的記錄具有相同的visit_date,會發生什麼情況?它拋出一個錯誤,討論子選擇返回多於一行。 – 2012-08-14 08:37:03

+0

@AmirPashazadeh:剛剛修復。如果這種情況在Visits表中可能,我只是將MAX()添加到所有子查詢中來處理這種情況。 – valex 2012-08-14 08:49:40

相關問題