Oracle XOR условие с> 14 таблицами - PullRequest
0 голосов
/ 14 сентября 2018

У меня вопрос по sql desgin.

Контекст: У меня есть таблица с именем t_master и 13 других таблиц (давайте назовем их a, b, c ... для простоты), где ее нужно сравнить.

Логика:

  • t_master будет сравниваться с таблицей 'a', где t_master.gen_val = a.value.
  • Если запись существует в t_master, получить запись t_master, иначе получить запись «a».
  • Мне не нужно извлекать записи, если они существуют в обеих таблицах (t_master и a) - условие XOR
  • Повторите это сравнение с оставшимися 12 таблицами.

У меня есть некоторая идея сделать это, используя WITH для предварительного запроса неосновных таблиц (a, b, c ...) сначала с их соответствующим предложением WHERE. Затем используйте оператор XOR для извлечения записей.

Что-то вроде

WITH a AS (SELECT ...),
b AS (SELECT ...) 

SELECT field1,field2...
FROM t_master FULL OUTER JOIN a FULL OUTER JOIN b FULL OUTER JOIN c...
ON t_master.gen_value = a.value
WHERE ((field1 = x OR field2 = y ) AND NOT (field1 = x AND field2 = y)) 
AND ....
.
.
.
.

Учитывая, что у меня есть 13 таблиц, которые мне нужны для полного внешнего соединения, есть ли лучший способ / дизайн для этого? В противном случае у меня было бы как минимум 2 * 13 строк предложения WHERE, но я не уверен, повлияет ли это на производительность, поскольку t_master является своего рода таблицей журналов.

** Предположим, я не могу изменить любую схему. В настоящее время я не уверен, будет ли этот SQL работать правильно, поэтому я надеюсь, что кто-то может направить меня в этом направлении.

обновление по предложению used_by_already:

Это то, что я пытаюсь сделать (сначала сравните две таблицы, прежде чем добавить еще, но я не могу получить значения из ATP_R.TBL_HI_HDR HI_HDR, как в подзапросе NOT EXISTS.
Как мне преодолеть это?

SELECT LOG_REPO.UNIQ_ID,
  LOG_REPO.REQUEST_PAYLOAD,
  LOG_REPO.GEN_VAL,
  LOG_REPO.CREATED_BY,
  TO_CHAR(LOG_REPO.CREATED_DT,'DD/MM/YYYY') AS CREATED_DT,
  HI_HDR.HI_NO R_VALUE,
  HI_HDR.CREATED_BY R_CREATED_BY,
  TO_CHAR(HI_HDR.CREATED_DT,'DD/MM/YYYY') AS R_CREATED_DT
FROM ATP_COMMON.VW_CMN_LOG_GEN_REPO LOG_REPO JOIN ATP_R.TBL_HI_HDR HI_HDR ON LOG_REPO.GEN_VAL = HI_HDR.HI_NO
WHERE NOT EXISTS
  (SELECT NULL
  FROM ATP_R.TBL_HI_HDR HI_HDR
  WHERE LOG_REPO.GEN_VAL = HI_HDR.HI_NO
  )

UNION ALL

SELECT LOG_REPO.UNIQ_ID,
  LOG_REPO.REQUEST_PAYLOAD,
  LOG_REPO.GEN_VAL,
  LOG_REPO.CREATED_BY,
  TO_CHAR(LOG_REPO.CREATED_DT,'DD/MM/YYYY') AS CREATED_DT,
  HI_HDR.HI_NO R_VALUE,
  HI_HDR.CREATED_BY R_CREATED_BY,
  TO_CHAR(HI_HDR.CREATED_DT,'DD/MM/YYYY') AS R_CREATED_DT
FROM ATP_R.TBL_HI_HDR HI_HDR JOIN ATP_COMMON.VW_CMN_LOG_GEN_REPO LOG_REPO ON HI_HDR.HI_NO = LOG_REPO.GEN_VAL
WHERE NOT EXISTS
  (SELECT NULL
  FROM ATP_COMMON.VW_CMN_LOG_GEN_REPO LOG_REPO
  WHERE HI_HDR.HI_NO = LOG_REPO.GEN_VAL
  ) 

1 Ответ

0 голосов
/ 14 сентября 2018

Полные внешние объединения, используемые для исключения всех совпадающих строк, могут быть дорогостоящим запросом. Вы не предоставляете много подробностей, но возможно с использованием NOT EXISTS будет проще, а возможно даст лучший план объяснения. Что-то в этом роде.

select
        cola,colb,colc
from t_master m
where not exists (
      select  null from a where m.keycol = a.fk_to_m
      )
and not exists (
      select  null from b where m.keycol = b.fk_to_m
      )
and not exists (
      select  null from c where m.keycol = c.fk_to_m
      )
union all
    select 
        cola,colb,colc from a
    where not exists (
          select  null from t_master m where a.fk_to_m = m.keycol
          )
union all
    select 
        cola,colb,colc from b
    where not exists (
          select  null from t_master m where b.fk_to_m = m.keycol
          )
union all
    select 
        cola,colb,colc from c
    where not exists (
          select  null from t_master m where c.fk_to_m = m.keycol
          )

Вы могли бы объединить таблицы 13 a, b, c ... для упрощения кодирования, но это может работать не так хорошо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...