我知道有关查询的每一个问题都可能有所不同,所以我仍然希望早些时候没有回答这个问题 我正在经过优化的Oracle sql查询,它将扫描多个表。
让我告诉你我的要求:
我们有一个UNIQUEREFERENCE表,我们在参考字段的散列(Varchar)的组合中插入entitykey(我们说A,B和C的3个主要实体),如下所示:
UNIQUEREFERENCEKEY REFERENCENAME REFERENCE IDENTIFIER1 IDENTIFIER2 SEQUENCE ORIGINALAKEY ORIGINALBKEY ORIGINALCKEY ORIGINALENTITYTYPE ORIGINALDISPLAYENTITYID REFERENCETIME ID3
现在我必须编写一个不应该从上表中带来任何行的查询,确保3个实体中没有一个具有“已拒绝”或“已取消”状态。如果返回了一些行,那么我们将其视为A或B或C的副本,基于ORIGINALENTITYTYPE。
如果没有返回任何内容,那么我们在此表中插入新引用并继续处理。
到目前为止我的尝试:
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
然后是实体表A
s.no reference status
1 XYZ1234 Rejected
2 XYZ4561 Processed
3 XYZ7891 Cancelled
然后是实体表B
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
从上面的uniquereference数据我不希望在entityType为A或C的情况下返回第1行或第3行,因为A和C的相应引用(XYZ1234,XYZ8910)的状态分别为Rejected / Cancelled。 虽然将返回uniquereference的第2行,因为实体B未被拒绝或取消,因此该引用无法重复使用,并且对于此用例,它将是重复的。
答案 0 :(得分: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