我有一个表TABLE,它有两个字段OLD_ID,NEW_ID表示合并数据的ID。
我们可以
(OLD_ID = '1',NEW_ID = '20' )
或
(OLD_ID = '4',NEW_ID = '50' )
(OLD_ID = '50',NEW_ID = '70' )
等。没有无限循环,但可能有许多原始id的合并,因此链可以是2,3,4,更长。
如何编写一个返回给定长度的所有链的查询?
我开始喜欢
select * from TABLE t1 as m1 where NEW_ID in
(select OLD_ID from t1 as m2 where OLD_ID in
(select NEW_ID from t1 as m3 where m1.NEW_ID <> NEW_ID))
但这不起作用且不可扩展。
答案 0 :(得分:1)
Oracle可以使用connect by
来执行此操作:Connect by提供了几个可能有用的伪列。
with CTE (Old_ID, New_ID) as (
Select 0,1 from dual union all
Select 1,2 from dual union all
Select 2,3 from dual union all
Select 3,4 from dual union all
Select 4,5 from dual union all
Select 5,6 from dual union all
Select 7,8 from dual union all
Select 8,9 from dual union all
Select 9,10 from dual union all
Select 10,11 from dual union all
Select 12,13 from dual)
SELECT Old_ID OID
, New_ID NID
, level lvl
, SYS_CONNECT_BY_PATH(OLD_ID, '/') "Path" --not needed but nice pseudo col
, CONNECT_BY_ISLEAF "IsLeaf" --needed to exclude subchains.
FROM cte A --Update this line w/ your table name
WHERE --LEVEL = 1 and
CONNECT_BY_ISLEAF =1 --this is how we only look at chains that have no other siblings
Start with OLD_ID not in (Select new_ID from CTE) --This ensures we look only at values that are themselves not new_IDs In other words, the oldest ancestor). -- and update the cte table name in the subquery here to your table name
connect by NOCYCLE prior new_ID=OLD_ID --added nocycle.
因为这允许您只遍历整个结构一次。看一下整个链条的长度而不是细分它。 isleaf确保我们只查看具有完整链的记录来确定链长。
这给了我们:
+----+----+---+--------------+----+
|OID |NID |LVL| Path |leaf|
+----+----+---+--------------+----+
| 5 | 6 | 6 | /0/1/2/3/4/5 | 1 |
| 10 | 11 | 4 | /7/8/9/10 | 1 |
| 12 | 13 | 1 | /12 | 1 |
+----+----+---+--------------+----+
您可以取消注释level = 1
并替换所需的级别。
您可能需要减去1,具体取决于您计算等级的方式。有些人喜欢从0开始;这从1开始。
答案 1 :(得分:0)
您可以使用递归CTE:
With Cte As
(
Select Old_Id, New_Id, 1 As Level
From YourTable
Where Old_Id = 4
Union All
Select T2.Old_Id, T2.New_Id, T1.Level + 1
From Cte T1
Join YourTable T2 On T1.New_Id = T2.Old_Id
)
Select *
From Cte
Order By Level
答案 2 :(得分:0)
如果链接数量有限,可能只是加入一个超出您认为需要的数量,而不是递归地写它:
select T1.OLD_ID as ID1
, T1.NEW_ID as ID2
, T2.NEW_ID as ID3
, T3.NEW_ID as ID4
, T4.NEW_ID as ID5
, T5.NEW_ID as ID6
, T6.NEW_ID as ID7
from table T1
left join table T2
on T1.NEW_ID = T2.OLD_ID
left join table T3
on T2.NEW_ID = T3.OLD_ID
left join table T4
on T3.NEW_ID = T4.OLD_ID
left join table T5
on T4.NEW_ID = T5.OLD_ID
left join table T6
on T5.NEW_ID = T6.OLD_ID