2011-11-22 47 views
3

我有兩個表:一個主要的APPLICATION表,它包含核心數據,一個STATUSTRACKING表反映了APPLICATION表中核心數據的狀態變化。如何從基於多個表的Oracle結果集中刪除重複項

APPLICATION表和STATUSTRACKING表之間存在1:N關係。舉例如下:

-- APPLICATION 
SELECT A.ID, A.DECISIONON, A.APPLICATIONSTATUS_ID AS CURRENTSTATUS 
FROM APPLICATION A 
WHERE A.ID=1099; 

Results: 
ID  DECISIONON CURRENTSTATUS 
1099 5/05/2009 5 

-- STATUS TRACKING 
SELECT ST.ID, ST.APPLICATION_ID AS APP_ID, ST.APPLICATIONSTATUS_ID AS STATUS, ST.CREATEDATE 
FROM STATUSTRACKING ST 
WHERE ST.APPLICATION_ID=1099 
ORDER BY ST.CREATEDATE DESC; 

Results: 
ID  APP_ID STATUS CREATEDATE 
44466 1099 5  5/05/2009 
44458 1099 7  5/05/2009 
10826 1099 8  21/07/2008 
9770 1099 7  9/07/2008 
4410 1099 3  9/05/2008 
3814 1099 2  2/05/2008 
3803 1099 1  2/05/2008 

問題: 我需要一個特定狀態的最近日期來選擇STATUSTRACKING記錄。這是我的嘗試:

SELECT A.ID AS APP_ID, A.APPLICATIONSTATUS_ID AS CURR_ST, Z.ID AS ST_ID, Z.CREATEDATE, Z.APPLICATIONSTATUS_ID AS OLD_ST 
FROM APPLICATION A, STATUSTRACKING Z 
WHERE A.APPLICATIONSTATUS_ID in (5,6) 
    AND A.ID IN (337,1099,1404,9441) 
    AND Z.APPLICATIONSTATUS_ID = 7 
    AND Z.APPLICATION_ID=A.ID 
ORDER BY A.ID ASC, Z.CREATEDATE DESC; 

Results: 
APP_ID CURR_ST ST_ID  CREATEDATE OLD_ST 
337  6  13978  17/08/2008 7 
1099 5  44458  5/05/2009 7 
1099 5  9770  9/07/2008 7 
1404 6  15550  28/08/2008 7 
9441 5  49271  3/06/2009 7 
9441 5  46058  13/05/2009 7 

問題是重複的行。我只能用最近的CreateDate顯示該行。在App_ID 1099的情況下,它應該是這樣的記錄:

1099 5  44458  5/05/2009 7 

我顯然不想排除沒有重複的行。

我以爲我是在正確的軌道上這個說法這給我在尋找該行:

SELECT A.ID, A.APPLICATION_ID, A.APPLICATIONSTATUS_ID, A.CREATEDATE 
FROM (SELECT * 
      FROM STATUSTRACKING 
      WHERE APPLICATIONSTATUS_ID=7 
       AND APPLICATION_ID=1099 
      ORDER BY CREATEDATE DESC) A 
WHERE ROWNUM = 1; 

...但我似乎無法得到它與我的主要工作選擇聲明。

的結果集我想應該是這樣的:

APP_ID CURR_ST ST_ID  CREATEDATE OLD_ST 
337  6  13978  17/08/2008 7 
1099 5  44458  5/05/2009 7 
1404 6  15550  28/08/2008 7 
9441 5  49271  3/06/2009 7 
etc. ... 

我沒有甲骨文/ SQL專家,所以任何幫助,將不勝感激。

回答

3

最簡單的方法可能是使用分析函數。像

SELECT * 
    FROM (
    SELECT A.ID AS APP_ID, 
      A.APPLICATIONSTATUS_ID AS CURR_ST, 
      Z.ID AS ST_ID, 
      Z.CREATEDATE, 
      Z.APPLICATIONSTATUS_ID AS OLD_ST, 
      rank() over (partition by a.id order by z.createDate desc) rnk 
     FROM APPLICATION A, 
      STATUSTRACKING Z 
    WHERE A.APPLICATIONSTATUS_ID in (5,6) 
     AND A.ID IN (337,1099,1404,9441) 
     AND Z.APPLICATIONSTATUS_ID = 7 
     AND Z.APPLICATION_ID=A.ID 
    ) 
WHERE rnk = 1 

的東西,如果可以有關係,你可能想使用ROW_NUMBERDENSE_RANK解析函數,而不是RANK

+0

棒極了! 這項工作沒有修改。感謝您的教育。 – user1058946

0

如果我理解正確,你想要的應用程序的最新狀態,對不對?問題:你的創建日期也有時間(小時,分鐘和秒)?也許這個查詢可以幫助您:

select a.* , st.* 
    from application a 
    , statustracking st 
where a.id = st.app_id 
    and st.createdate = (select max(st1.createdate) 
          from statustracing st1 
          where st1.app_id = a.id 
          and st1.application_statusid = st.application_statusid ) 
    -- filters goes there 
    and a.id in (....) 
    and st.application_statusid in (...) 
+0

謝謝你。通過一兩個調整來匹配我的語法,這個解決方案也可以工作!謝謝。 – user1058946