优化Oracle中的递归查询

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

我在 Oracle 中遇到递归查询问题。

假设我有一个带有结构的表“NAMES”:

财产 姓名 参考
0 迈克 1
1 约翰 4
1 詹姆斯 4
1 罗伯特 4
4 迈克尔 5
5 大卫 6
6 马克

和简单的递归查询:

WITH rec as
(
 SELECT N_1.PROPERTY, N_1.NAME, N_1.REFERENCE 
 FROM NAMES N_1
 WHERE PROPERTY = 0
 UNION ALL
 SELECT N_2.PROPERTY, N_2.NAME, N_2.REFERENCE  
 FROM NAMES N_2
 JOIN rec r ON T_2.PROPERTY = r.REFERENCE
)
SELECT NAME FROM rec;

女巫给出:

姓名
迈克
詹姆斯
约翰
罗伯特
迈克尔
迈克尔
迈克尔
大卫
大卫
大卫
马克
马克
马克

因此,一切正常。但问题是:对于迈克 - 找到 3 条记录:詹姆斯、约翰、罗伯特(没关系) - 然后为他们每个人找到迈克尔(3 次,再次好吧) - 但然后为每个迈克尔的出现找到它自己的大卫(但是这是相同的大卫,对于相同的迈克尔!) - 然后对于每个大卫都找到了它自己的马克(对于相同的马克 - 相同的大卫)。

我的目标只是找到从 Mike 开始的完整层次结构,即找到从 Mike 按 REFERENCE = PROPERTY 行走可以到达的所有元素。所以,我想要的结果集如下所示:

姓名
迈克
詹姆斯
约翰
罗伯特
迈克尔
大卫
马克

我知道通过添加“DISTINCT”我可以实现我的目标:

...
SELECT DISTINCT NAME FROM rec;

但重点是,无论如何都会找到额外的记录(过多的 Davids 和 Marks ) - 但只会从结果中丢弃。这对我来说很糟糕,因为我的真实表格比示例复杂得多,并且额外的搜索需要花费大量时间。 那么,有没有办法对数据库说——“如果你找到迈克尔 3 次——不要搜索他的参考文献 3 次——只搜索一次”。

提前致谢:)

附注首先我想到的是做类似的事情:

WITH rec as
(
...
 UNION ALL
 SELECT DISTINCT N_2.PROPERTY, N_2.NAME, N_2.REFERENCE  
 FROM NAMES N_2
 JOIN rec r ON T_2.PROPERTY = r.REFERENCE
)
SELECT NAME FROM rec;

但是 Oracle 不喜欢它。

database oracle recursive-query
1个回答
0
投票

一种方法可能是找到

DISTINCT
property
reference
对,然后生成层次结构并将
JOIN
返回到
NAMES
表以获取名称:

WITH relationships (property, reference) AS (
  SELECT DISTINCT property, reference
  FROM   names
),
hierarchy (property) AS (
  SELECT property
  FROM   relationships
  START WITH property = 0
  CONNECT BY PRIOR reference = property
)
SELECT n.name
FROM   hierarchy h
       INNER JOIN names n
       ON (h.property = n.property)

WITH relationships (property, reference) AS (
  SELECT DISTINCT property, reference
  FROM   names
),
hierarchy (property, reference) AS (
  SELECT property, reference
  FROM   relationships
  WHERE  property = 0
UNION ALL
  SELECT r.property, r.reference
  FROM   hierarchy h
         INNER JOIN relationships r
         ON h.reference = r.property
)
SELECT n.name
FROM   hierarchy h
       INNER JOIN names n
       ON (h.property = n.property)

哪个输出:

姓名
迈克
约翰
詹姆斯
罗伯特
迈克尔
大卫
马克

小提琴

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