[英]Recursive CTE with 2 tables not working in Oracle / SQL
There are 2 tables Department
and subdepartment
which have id in common. 有2个表Department
和subdepartment
Department
具有共同的ID。 I am trying to recursively fetch all the ids reporting to AB directly and indirectly. 我试图递归地获取直接和间接向AB报告的所有ID。 BC is reporting to AB, hence 4,5,6 are indirectly reporting to AB, likewise fetching till the last id. BC向AB报告,因此4,5,6间接向AB报告,同样获取直到最后一个ID。
Tried the below recursive CTE
query but I am getting the result of only the first level. 尝试了下面的递归CTE
查询,但是我只得到第一级的结果。 Seems recursive
query is not executing. 似乎recursive
查询未执行。
I am not sure what is wrong in the query. 我不确定查询中出了什么问题。 Can someone help me in spotting the error. 有人可以帮助我发现错误。
Department 部
Name id
AB 1
AB 2
AB 3
BC 4
BC 5
BC 6
CD 7
CD 8
EF 9
EF 10
EF 11
Subdepartment SUBDEPARTMENT
ID Reporting
1
2
3 BC
4
5 CD
6
7
8 EF
9
10
11
Query: 查询:
With reportinghierarchy (Name, Id, Reporting, Level) As
(
--Anchor
Select A.name,A.id,reporting,0 from department A, subdepartment B
where A.id=B.id and A.name='AB'
Union All
--Recursive member
Select C.name,C.id,D.reporting, Level+1 from department C, subdepartment D
Inner Join reportinghierarchy R
On (C.Name = R.reporting)
Where C.name != 'AB' and C.Id =D.id
And R.Reporting is not null
)
Select * from reportinghierarchy
Current Output : 电流输出
Name Id Reporting Level
AB 1 0
AB 2 0
AB 3 BC 0
Expected output : 预期产量:
Name id Reporting Level
AB 1 0
AB 2 0
AB 3 BC 0
BC 4 1
BC 5 CD 1
BC 6 1
CD 7 2
CD 8 EF 2
EF 9 3
EF 10 3
EF 11 3
Hmmm, "horrible data structure" comes to mind. 嗯,“可怕的数据结构”浮现在脑海。 This approach gets one row per "reporting" name to use for the recursive CTE portion. 此方法为每个“报告”名称获取一行以用于递归CTE部分。 It then joins the level back to the original data. 然后,它将级别返回到原始数据。
with ds as (
select d.name, d.id, sd.reporting
from department d join
subdepartment sd
on d.id = sd.id
),
nd as (
select d.name, sd.reporting
from ds
where sd.reporting is not null
),
cte as (
select ds.name, nd.reporting, 0 as lev
from nd
where not exists (select 1 from nd nd2 where nd2.reporting = nd.name)
union all
select nd.name, nd.reporting, lev + 1
from cte join
nd
on nd.name = cte.reporting
)
select ds.*, cte.lev
from ds join
cte
on ds.name = cte.name;
Also, learn to use proper, explicit JOIN
syntax. 另外,学习使用正确的显式JOIN
语法。 It has been the standard syntax for decades. 数十年来,它一直是标准语法。
Your original query was actually VERY, VERY close to working. 您原来的查询实际上非常非常接近。 The reasons it didn't work are: 它不起作用的原因是:
LEVEL
as a column name without quoting it. 您使用关键字LEVEL
作为列名而不引用它。 In Oracle LEVEL
has specific meaning, and using it out of context causes the parser no end of headaches. 在Oracle中, LEVEL
具有特定的含义,在上下文之外使用它会使解析器无休止地头痛。 I've changed it to LVL
, which works fine. 我将其更改为LVL
,它可以正常工作。 The corrected query is: 更正后的查询是:
With reportinghierarchy (Name, Id, Reporting, lvl) As
(
--Anchor
Select A.name,A.id,reporting,0 from department A, subdepartment B
where A.id=B.id and A.name='AB'
Union All
--Recursive member
Select C.name,C.id,D.reporting, lvl+1 from department C, subdepartment D, reportinghierarchy R
Where C.name != 'AB' and C.Id =D.id and C.Name = R.reporting
And R.Reporting is not null
)
Select * from reportinghierarchy;
Given the above, the following results are returned, which appear to match your desired results: 鉴于以上所述,将返回以下结果,这些结果似乎与您期望的结果相匹配:
NAME ID REPORTING LVL
AB 1 (null) 0
AB 2 (null) 0
AB 3 BC 0
BC 4 (null) 1
BC 5 CD 1
BC 6 (null) 1
CD 7 (null) 2
CD 8 EF 2
EF 9 (null) 3
EF 10 (null) 3
EF 11 (null) 3
Best of luck. 祝你好运。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.