2016-10-03 68 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