将使用EXISTS/NOT EXISTS的查询转换为三个表连接

xzv2uavs  于 2022-09-18  发布在  Java
关注(0)|答案(1)|浏览(225)

我正在做一个问题陈述,其中我需要保留基于三个表上应用的逻辑的记录。表如下所列。

表A:
|Id|phone_number|帐号名称
|-|-|
|123|80001|1001

表_B

|Id|phone_number|帐号名称
|-|-|
|124|80002|1002

表_C

|Id|phone_number|帐号名称
|-|-|
|125|80003|1003

我编写了一个查询,如下所示:

select /*+PARALLEL(su,8)*/ su.ID from TableA su where
(
EXISTS (select /*+ PARALLEL(sa,8) PARALLEL(su,8)*/ PHONE_NUMBER from TableB sa where PHONE_NUMBER=su.PHONE_NUMBER)
or EXISTS (select /*+ PARALLEL(sa,8) PARALLEL(su,8)*/ PHONE_NUMBER from TableC sa where PHONE_NUMBER=su.PHONE_NUMBER)
)
and
(
EXISTS (select /*+ PARALLEL(sa,8) PARALLEL(su,8)*/ ACCOUNT_NAME from TableB sa where ACCOUNT_NAME=su.ACCOUNT_NAME)
or EXISTS (select /*+ PARALLEL(sa,8) PARALLEL(su,8)*/ ACCOUNT_NAME from TableC sa where ACCOUNT_NAME=su.ACCOUNT_NAME)
)
and
NOT EXISTS (select /*+ PARALLEL(sa,8) PARALLEL(su,8)*/ ID from TableC sa where ID=su.ID)
and NOT EXISTS (select /*+ PARALLEL(sa,8) PARALLEL(su,8)*/ ID from TableB sa where ID=su.ID);

我这里的要求是,对于表A的记录,如果Phone_Number和Account_NAME在TableB或TableC中,并且ID不在这两个表中的任何一个表中,那么记录应该存在。现有代码在大多数情况下都可以工作,但有一个特定的场景是不起作用的,其中对于表A的特定记录,Account_NAME和Phone_Number存在于TableB或TableC中的两个不同的记录中。我想从我的输出中排除这类记录,因此我尝试将查询转换为三向联接,以便在特定记录上进行联接。我写的查询如下-

select su.id from TableA su,TableB sa,TableC sb where (su.PHONE_NUMBER=sa.PHONE_NUMBER OR su.PHONE_NUMBER=sb.PHONE_NUMBER) and (su.ACCOUNT_NAME=sa.ACCOUNT_NAME OR su.ACCOUNT_NAME=sb.ACCOUNT_NAME) 
and NOT EXISTS (select /*+ PARALLEL(sa,8) PARALLEL(su,8)*/ id from TableC sa where id=su.id)
and NOT EXISTS (select /*+ PARALLEL(sa,8) PARALLEL(su,8)*/ id from TableB sa where id=su.id);

该查询返回许多重复项,我也尝试使用DISTINCT,但仍然得到不正确的结果。

有人能告诉我我的问题出了什么问题吗?敬请指教。

谢谢!

vsdwdz23

vsdwdz231#

我还是不能肯定我是否明白你的要求。下面的查询查找TableA行,其中TableB或TableC中存在具有相同的ACCOUNT_NAME/PHONE_NUMBER对但ID不同的行。

select *
from tablea a
where exists
(
  select null
  from tableb b
  where b.phone_number = a.phone_number
    and b.account_name = a.account_name
    and b.id <> a.id
)
or exists
(
  select null
  from tablec c
  where c.phone_number = a.phone_number
    and c.account_name = a.account_name
    and c.id <> a.id
)
order by id;

如果你想看到其他的ID,你必须加入。我建议将TableB和TableC结合起来:

select a.*, bc.table_name, bc.id as other_table_id
from tablea a
join
(
  select 'TableB' as table_name, id, phone_number, account_name from tableb
  union all
  select 'TableC' as table_name, id, phone_number, account_name from tablec
) bc on bc.phone_number = a.phone_number
    and bc.account_name = a.account_name
    and bc.id <> a.id
order by a.id, bc.table_name, bc.id;

相关问题