2012-05-23 174 views
0

在Oracle 9.2.0.8中,我需要返回一個特定字段(LAB_SEQ)最大的記錄集(它是一個連續的VARCHAR數組'0001','0002'等)對於每個另一個字段(WO_NUM)。要選擇最大值,我試圖按降序排列並選擇第一行。我在StackOverflow上找到的所有東西都表明,唯一的方法是使用相關的子查詢。然後,我用這個最大外部查詢的WHERE子句中得到我想要每個WO_NUM行:在Oracle中避免相關子查詢

SELECT lt.WO_NUM, lt.EMP_NUM, lt.LAB_END_DATE, lt.LAB_END_TIME 
FROM LAB_TIM lt WHERE lt.LAB_SEQ = (
    SELECT LAB_SEQ FROM (
     SELECT lab.LAB_SEQ FROM LAB_TIM lab WHERE lab.CCN='1' AND MAS_LOC='1' 
      AND lt.WO_NUM = lab.WO_NUM ORDER BY ROWNUM DESC 
    ) WHERE ROWNUM=1 
) 

然而,這個返回lt.WO_NUM錯誤的無效的標識符。研究表明,ORACLE 8只允許相關的子查詢達到一個深度,並且建議重寫以避免子查詢 - 這是關於選擇最大值的討論暗示無法完成的事情。任何幫助得到這個聲明執行將不勝感激。

+3

由ROWNUM訂購在這裏並不是非常有用。 – DCookie

回答

3

你的相關子查詢將需要像

SELECT lt.WO_NUM, lt.EMP_NUM, lt.LAB_END_DATE, lt.LAB_END_TIME 
FROM LAB_TIM lt WHERE lt.LAB_SEQ = (
    SELECT max(lab.LAB_SEQ) 
    FROM LAB_TIM lab 
    WHERE lab.CCN='1' AND MAS_LOC='1' 
     AND lt.WO_NUM = lab.WO_NUM 
) 

既然你是在Oracle 9.2,它可能會更有效地使用相關子查詢。我不確定lab.CCN='1' AND MAS_LOC='1'謂詞在當前查詢中的作用,所以我不太確定如何將它們轉換爲分析函數方法。 中LAB_SEQWO_NUM的組合不唯一嗎?您是否需要在CCNMAS_LOC的謂詞中添加以便爲每個WO_NUM獲取一個唯一的行?還是你使用這些謂詞來減少輸出中的行數?其基本做法會像

SELECT * 
    FROM (SELECT lt.WO_NUM, 
       lt.EMP_NUM, 
       lt.LAB_END_DATE, 
       lt.LAB_END_TIME, 
       rank() over (partition by wo_num 
           order by lab_seq desc) rnk 
      FROM LAB_TIM lt) 
    WHERE rnk = 1 

,但它不是很清楚,我是否CCNMAS_LOC需要被添加到ORDER BY子句中的解析函數或是否需要添加到WHERE條款。

+1

+1,雖然8i已經有[analytics](http://docs.oracle.com/cd/A87860_01/doc/server.817/a85397/function.htm#81409):) –

+0

@VincentMalgrat - 你說得對 - 看起來像8.1.6中介紹的那樣。 –

+0

謝謝,賈斯汀。雖然這實現了我的目標,但卻遭受了嚴重的低效率。由於max()函數會迭代表中的每個條目(這很大),所以我想利用這樣的事實,即行實際上是按順序排列的。我認爲ROWNUM的排序比LAB_SEQ更有效,因爲比較字符串非常耗時。您建議的查詢現在已經運行了大約5分鐘,看不到任何結果。 – user1412922

0

這是相關子查詢更好的一種情況,特別是在表上有索引的情況下。但是,應該可以將相關的子查詢重寫爲連接。

我認爲下面是等價的,不相關子查詢:

SELECT lt.WO_NUM, lt.EMP_NUM, lt.LAB_END_DATE, lt.LAB_END_TIME 
FROM (select *, rownum as r 
     from LAB_TIM lt 
    ) lt join 
    (select wo_num, max(r) as maxrownum 
     from (select LAB_SEQ, wo_num, rownum as r 
      from LAB_TIM lt 
      where lab.CCN = '1' AND MAS_LOC = '1' 
      ) 
    ) ltsum 
    on lt.wo_num = ltsum.wo_num and 
     lt.r = ltsum.maxrownum 

我有點不確定甲骨文如何處理的事情rownums像ORDER BY。