如何编写 SQL 脚本来查找与原始 ID 相关的所有关系?

Posted

技术标签:

【中文标题】如何编写 SQL 脚本来查找与原始 ID 相关的所有关系?【英文标题】:How do I write a SQL script to find all relationships tied to an original id? 【发布时间】:2020-06-09 08:33:52 【问题描述】:

例如:

我想传入一个税号以查找与此税号关联的所有帐户。这只是:

SELECT TAX_ID, ACCOUNT_NUMBER FROM CUSTOMER_RECORDS

然后我会有一个所有帐户的列表。但是,每个账户也可以有其他相关的税号(共同借款人、担保人等)。因此,我想获取退回的帐户,然后找到与它们关联的所有税号。然后,我需要重复这些步骤以查找与返回的所有新税号相关联的所有帐户。

最终结果将是所有形成一个“关系”的帐户和税号的列表。

我在想递归 CTE 可能适用于这种情况?但是,这比我的 SQL 技能水平高一点。我将不胜感激。

【问题讨论】:

您是否真的会无限使用这个直到您拥有可能与税号相关的所有内容,或者只是深入您描述的 3 层? 您的问题假定您对您的数据有一定程度的熟悉,但并未提供这种熟悉程度。如何定义“关联”ID?它可以从一张表中导出,还是需要两张或多张?为了帮助我们帮助您,请通读How To Ask,然后使用创建a Minimal, Complete, and Verifiable Example 所需的详细信息编辑您的问题。 @babno 我希望它返回所有可能的结果。 @EricBrandt 涉及一个表和该表中的两列。我在我的问题中提供了这些。 好的。由于所需的所有信息都在问题中,我们可以坐下来看着答案滚滚而来。 【参考方案1】:

很确定您可以使用hierarchical query 做到这一点。请谨慎使用 - 如果您不小心,这些事情可能会远离您,然后您会接到 DBA 的电话“为什么查询运行了 6 天”。示例:

with base_data as
(
  select 1 as tax_id, 'A' as account_number from dual union all
  select 1 as tax_id, 'B' as account_number from dual union all
  select 2 as tax_id, 'A' as account_number from dual union all
  select 2 as tax_id, 'B' as account_number from dual union all
  select 2 as tax_id, 'C' as account_number from dual union all
  select 3 as tax_id, 'D' as account_number from dual union all
  select 3 as tax_id, 'E' as account_number from dual union all
  select 4 as tax_id, 'E' as account_number from dual union all
  select 4 as tax_id, 'F' as account_number from dual union all
  select 5 as tax_id, 'A' as account_number from dual union all
  select 5 as tax_id, 'F' as account_number from dual union all
  select 6 as tax_id, 'G' as account_number from dual union all
  select 7 as tax_id, 'H' as account_number from dual union all
  select 7 as tax_id, 'I' as account_number from dual union all
  select 8 as tax_id, 'I' as account_number from dual union all
  select 8 as tax_id, 'K' as account_number from dual
)

select distinct bd.*
from base_data bd
start with tax_id = :taxID
connect by nocycle (prior account_number = account_number or prior tax_id = tax_id)
--and level <= 10
order by 1, 2

正如所写,注释掉“and level

【讨论】:

【参考方案2】:

请尝试以下方法:

with customer_records as
(
select 111 tax_id, 0 account_number from dual union
select 1 , 100 from dual union
select 1 , 200 from dual union
select 1 , 300 from dual union
select 1 , 400 from dual union
select 2 , 100 from dual union
select 3 , 202 from dual union
select 4 , 303 from dual union
select 5 , 400 from dual union
select 0 , 222 from dual 
)
SELECT c1.TAX_ID, c1.ACCOUNT_NUMBER 
FROM CUSTOMER_RECORDS c1
where 1=1
  and c1.tax_id = :tax_id
union
SELECT c2.TAX_ID, c2.ACCOUNT_NUMBER 
FROM CUSTOMER_RECORDS c1
, CUSTOMER_RECORDS c2
where 1=1
  and c1.tax_id = :tax_id
  and c1.tax_id <> c2.tax_id 
  and c1.account_number = c2.account_number
;

【讨论】:

这似乎完全符合我的要求。我会用实际数据做一些测试并跟进。谢谢!! 我很高兴@Oomptz !祝你今天过得愉快!!!如果您不介意,可以投票/接受答案。 @Oomptz - 关键是“似乎”,除非你在开玩笑说要无限期地寻找关系。就像你在 cmets 中所说的那样。这个答案只得到第一层。 @dandarc 在我的测试中,这一直持续到找到所有关系为止。你有什么不同的经历吗? 将我的示例中的数据复制到这个示例中 - 你只会得到 5 行的 tax_id 1。如果你运行我的答案(编辑它 - 我第一次发布时错过了重命名字段的位置) ,你得到 11 行。因为这里只执行 2 个步骤 - 首先它找到与给定税号匹配的行。然后它从第一步中找到与帐号匹配的行。然后它停止。您在 cmets 中对问题说它应该一遍又一遍地重复,直到找到整个关系。您的真实数据是否像这样停止在 1 步?如果不是,则此方法不正确。

以上是关于如何编写 SQL 脚本来查找与原始 ID 相关的所有关系?的主要内容,如果未能解决你的问题,请参考以下文章

需要编写一个 sql 脚本来查找 oracle 中任何数据库的元数据详细信息

sql查找ID并在没有找到结果时插入

查找 T-SQL 以返回这些值

如何编写多对多的sql脚本

如何编写一个 JPQL 查询来查找此连接中未找到的记录?

[Oracle][Metadata]如何查找与某一个功能相关的数据字典名