Оптимизированный для нескольких таблиц запрос oracle sql

#sql #oracle #query-optimization

#sql #Oracle #оптимизация запросов

Вопрос:

Я знаю, что каждый вопрос в запросах может быть разным, поэтому я все еще надеюсь, что на этот вопрос не было ответа ранее.
Мне нужен оптимизированный запрос Oracle sql, который будет сканировать несколько таблиц.

Позвольте мне рассказать вам о своих требованиях :

У нас есть таблица UNIQUEREFERENCE, в которую мы вставляем entitykey (из 3 основных объектов, которые у нас есть, скажем, A, B и C) в сочетании с хешем ссылочных полей (Varchar), поскольку столбцы такие, как показано ниже :

 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 из entity table, чтобы убедиться, что мы не рассматриваем те объекты (A, B и C), статус которых («Отклонен», «Отменен»), и я пока не могу придумать идеальный оптимизированный запрос.

Любая помощь была бы очень признательна или любой лучший способ решить эту проблему с помощью одного SQL-запроса.

Спасибо.

Обновление: добавление образцов данных по запросу.

Таблица уникальных ссылок

 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 я не ожидаю, что строка 1 или 3 будет возвращена в случае, если EntityType равен A или C, потому что соответствующая ссылка (XYZ1234,XYZ8910) для A и C имеет статус Отклонено / Отменено соответственно.
В то время как строка 2 uniquereference будет возвращена как объект, B не отклоняется или не отменяется, и, следовательно, ссылка не может быть использована повторно, и она будет дублироваться для этого варианта использования.

Комментарии:

1. Примеры данных и желаемых результатов действительно помогут объяснить, что вы хотите сделать.

2. Обновлено по вашему запросу, дайте мне знать, если это прояснит ситуацию.

Ответ №1:

Мне не совсем понятны некоторые детали вашего использования, но этот подход может помочь, если я правильно понимаю:

 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