Использование существует, когда в подзапросе присутствует Union All

#mysql #sql #database #oracle-sqldeveloper

#mysql #sql #База данных #oracle-sqldeveloper

Вопрос:

Я хотел изменить запрос, который я написал с помощью IN оператора, на использование Exists оператора. Однако проблема в том, что у меня есть union all в моем подзапросе. Поскольку у меня нет большого опыта использования exists в таком сценарии, я искал некоторую помощь.

Это был первоначальный запрос:

 select APP_NUM,SBM_INDV_ID 
from T1004_APP_INDV indv 
where INDV.APP_NUM = 'T23952717' 
and INDV.SBM_INDV_ID in
  (select EMPL.INDV_ID 
   from DC_EMPLOYMENT EMPL 
   where EMPL.LOST_EMPLOYMENT_SW = 'N' 
   and EMPL.TERMINATION_DT is null 
   and (EMPL.EFF_END_DT is null 
     or EMPL.EFF_END_DT >= TRUNC(SYSDATE))     
   union all
   select UNEARN.INDV_ID 
   from DC_UNEARNED_INCOME UNEARN 
   where UNEARN.EFF_END_DT is null 
   or UNEARN.EFF_END_DT >= TRUNC(SYSDATE)  
   union all
   select RBINC.INDV_ID 
   from DC_ROOM_BOARD_INCOME RBINC 
   where RBINC.EFF_END_DT is null 
   or RBINC.EFF_END_DT >= TRUNC(SYSDATE)
   union all
   select SELFEMP.INDV_ID 
   from DC_SELF_EMP_INCOME SELFEMP 
   where SELFEMP.EFF_END_DT is null 
   or SELFEMP.EFF_END_DT >= TRUNC(SYSDATE)
);  
 

Я попытался изменить начальный запрос следующим образом:

 select APP_NUM,SBM_INDV_ID 
from T1004_APP_INDV APPINDV 
where APPINDV.APP_NUM = 'T23952717' 
and exists
  (select EMPL.INDV_ID 
   from DC_EMPLOYMENT EMPL 
   where APPINDV.SBM_INDV_ID = EMPL.INDV_ID 
   and EMPL.LOST_EMPLOYMENT_SW = 'N' 
   and EMPL.TERMINATION_DT is null 
   and (EMPL.EFF_END_DT is null 
     or EMPL.EFF_END_DT >= TRUNC(SYSDATE))     
   union all
   select UNEARN.INDV_ID 
   from DC_UNEARNED_INCOME UNEARN 
   where APPINDV.SBM_INDV_ID = UNEARN.INDV_ID 
   and UNEARN.EFF_END_DT is null 
   or UNEARN.EFF_END_DT >= TRUNC(SYSDATE)  
   union all
   select RBINC.INDV_ID 
   from DC_ROOM_BOARD_INCOME RBINC 
   where APPINDV.SBM_INDV_ID = RBINC.INDV_ID 
   and RBINC.EFF_END_DT is null 
   or RBINC.EFF_END_DT >= TRUNC(SYSDATE)
   union all
   select SELFEMP.INDV_ID 
   from DC_SELF_EMP_INCOME SELFEMP 
   where APPINDV.SBM_INDV_ID = SELFEMP.INDV_ID 
   and SELFEMP.EFF_END_DT is null 
   or SELFEMP.EFF_END_DT >= TRUNC(SYSDATE)); 
 

Корректен ли второй запрос? Дает ли это тот же результат, что и предыдущий запрос?

Спасибо

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

1. У вас есть данные, таблицы, база данных и код для проверки этого, но вы спрашиваете нас, является ли запрос синтаксически правильным и дает ли он те же результаты??????

2. На мой взгляд, это дает те же результаты для небольшого набора данных, с которым я работаю. Как я уже упоминал, я никогда не работал над сценарием, в котором я использовал exists с union all, присутствующим в подзапросе. Это подходящий способ сделать это?

Ответ №1:

Я думаю, что разделение этого на отдельные запросы упрощает оптимизатор:

 where APPINDV.APP_NUM = 'T23952717' and
      ( exists (select 1 
                from DC_EMPLOYMENT EMPL 
                where APPINDV.SBM_INDV_ID = EMPL.INDV_ID and
                      EMPL.LOST_EMPLOYMENT_SW = 'N' and
                      EMPL.TERMINATION_DT is null and
                     (EMPL.EFF_END_DT is null or EMPL.EFF_END_DT >= TRUNC(SYSDATE)
               ) or
        exists (select 1
                from DC_UNEARNED_INCOME UNEARN 
                where APPINDV.SBM_INDV_ID = UNEARN.INDV_ID and
                      ( UNEARN.EFF_END_DT is null and or UNEARN.EFF_END_DT >= TRUNC(SYSDATE) )
               ) or
        . . .
     )