2016-10-03 77 views
0

我知道關於查詢的每個問題都可能不同,所以我仍然希望這個問題沒有得到回答。
我在優化後的Oracle sql查詢將掃描多個表。多表優化oracle sql查詢

讓我告訴你我的要求:

我們有一個UNIQUEREFERENCE表,其中我們插入的EntityKey(我們有說A,B和C 3點主要的實體)在引用字段(VARCHAR)散列的組合列情況如下:

UNIQUEREFERENCEKEY REFERENCENAME REFERENCE IDENTIFIER1 IDENTIFIER2 SEQUENCE ORIGINALAKEY ORIGINALBKEY ORIGINALCKEY ORIGINALENTITYTYPE ORIGINALDISPLAYENTITYID REFERENCETIME ID3 

我現在必須寫一個查詢,不應該從上表帶來任何行,從而確保沒有3個實體有狀態爲「拒絕」或「取消」。如果有一行返回,則根據ORIGINALENTITYTYPE的內容將其視爲A或B或C的重複。

如果沒有返回任何內容,我們將在此表中插入新的引用,並繼續處理。

我試圖至今:

select 
      REFERENCENAME as referenceName, 
      REFERENCE as reference, 
      IDENTIFIER1 as Identifier1, 
      IDENTIFIER2 as Identifier2, 
      max(SEQUENCE) as maxSequence, 
      count(1) as totalCount, 
      min(ORIGINALDISPLAYENTITYID) keep (dense_rank first order by sequence) as firstDisplayId, 
      min(ID3) keep (dense_rank first order by sequence) as firstId3, 
      min(case 
        when 'com.example.domain.A' = :checkEntityName and ORIGINALENTITYTYPE = :checkEntityName and ORIGINALAKEY = :checkEntityKey 
         then ORIGINALAKEY 
        when 'com.example.domain.B' = :checkEntityName and ORIGINALENTITYTYPE = :checkEntityName and ORIGINALBKEY = :checkEntityKey 
         then ORIGINALBKEY 
        when 'com.example.domain.C' = :checkEntityName and ORIGINALENTITYTYPE = :checkEntityName and ORIGINALCKEY = :checkEntityKey 
         then ORIGINALCKEY 
        else null 
       end) as entityKey 
     from UNIQUEREFERENCE 
     where REFERENCENAME = :referenceName 
      and REFERENCE = :reference 
      and NVL(IDENTIFIER2, 'N/A') = NVL(:Identifier2, 'N/A') 
      and NVL(IDENTIFIER1, 'N/A') = NVL(:Identifier1, 'N/A') 
     group by REFERENCENAME, REFERENCE, IDENTIFIER1, IDENTIFIER2 

正如你所看到的參數checkEntityName和checkEntityKey在運行時將在此通用查詢被替換爲所有3個實體。

現在我只需要在實體表中爲3個entityKey建立一個連接,以確保我們不會考慮那些在(「拒絕」,「已取消」)中的狀態的實體(A,B和C)到目前爲止提出了一個完美優化的查詢。

任何幫助將真正讚賞或任何更好的方式來解決在一個單一的SQL查詢。

感謝。

更新:按要求添加樣本數據。

UniqueReference表

1 TEST1 XYZ1234 null ABCD SEQ12345 1231 null null com.example.domain.A null 
2 TEST2 XYZ4567 null ABCD SEQ12346 null 2341 null com.example.domain.B null 
3 TEST3 XYZ8910 null ABCD SEQ12347 null null 5671 com.example.domain.C null 

然後實體表阿

s.no reference status 
1  XYZ1234  Rejected 
2  XYZ4561  Processed 
3  XYZ7891  Cancelled 

然後實體表乙

s.no reference status 
1  XYZ4567  Processed 
2  XYZ6561  Processed 
3  XYZ8891  Cancelled 

然後實體表C中

s.no reference status 
1  XYZ8910  Cancelled 
2  XYZ8562  Processed 
3  XYZ1789  Cancelled 

從上面唯一的參考數據中我不希望行1或3在entityType爲A或C的情況下返回,因爲A和C的相應引用(XYZ1234,XYZ8910)分別具有拒絕/取消狀態。 儘管uniqueReference的第2行將被返回,因爲實體B沒有被拒絕或取消,因此引用不能被重用,並且在此用例中它將被重複。

+2

樣本數據和預期的結果將真正幫助解釋你想要什麼做。 –

+0

根據您的要求更新,請告訴我是否清楚。 – user1353436

回答

0

我不是一些爲您的使用細節完全清楚,但這種方法可以幫助,如果我理解正確:

SELECT UR.reference 
    , UR.fieldA 
    , UR.fieldB 
    , UR.fieldN 
    , COUNT(EntityA.sno) + 
     COUNT(EntityB.sno) + 
     COUNT(EntityC.sno) as subrecords 
FROM UniqueReference UR 
LEFT JOIN EntityA A 
    ON UR.reference = A.reference 
    AND A.status = 'PROCESSED' 
LEFT JOIN EntityB B 
    ON UR.reference = B.reference 
    AND B.status = 'PROCESSED' 
LEFT JOIN EntityC C 
    ON UR.reference = C.reference 
    AND C.status = 'PROCESSED' 
GROUP BY UR.reference 
HAVING subrecords > 0 
-- this may need to be: HAVING COUNT(EntityA.sno) + COUNT(EntityB.sno) + COUNT(EntityC.sno) > 0