具有> 14个表的Oracle SQL XOR条件

问题描述 投票:1回答:1

我对sql设计有疑问。

上下文:我有一个名为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来首先使用各自的WHERE子句对非主表(a,b,c ...)进行子查询。然后使用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的建议更新:

这就是我想要做的事情(首先在2个表之间进行比较,然后我添加更多,但我无法从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
  ) 
sql oracle
1个回答
0
投票

用于排除所有匹配行的完全外部联接可能是一个昂贵的查询。你没有提供太多的细节,但也许使用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 ...表联合起来以简化编码,但这可能表现不佳。

© www.soinside.com 2019 - 2024. All rights reserved.