Oracle SQL 左连接相同 table 循环次数未知
Oracle SQL Left join same table unknown amount of times with cycles
这是我之前问题的后续问题:
假设我有这个数据集
| old | new |
|------|-------|
| a | b |
| b | c |
| d | e |
| e | a | <- Here is a cycle
| ... | ... |
| aa | bb |
| bb | ff |
| ... | ... |
| 11 | 33 |
| 33 | 523 |
| 523 | 4444 |
| 4444 | 33 | <- another cycle
因为循环oracle returns这个错误:
"ORA-32044: cycle detected while executing recursive WITH query"
我想打破递归循环并检测导致循环的行
下面可以用“<”打破循环
with numbers(val) as (
select 1 as val from dual
union all
select val + 1 from numbers
where val < 5
)
select val from numbers
我尝试了以下方法:http://rextester.com/ITB3407
相同的代码:
with cte (old, new, lev) as
(
select old, new, 1 as lev from mytable
union all
select m.old, cte.new, cte.lev + 1
from mytable m
join cte on cte.old = m.new
where cte.lev < 6
)
select old, max(new) keep (dense_rank last order by lev) as new
from cte
group by old
order by old;
添加 CYCLE
子句。通过指定此子句,检测到循环并停止递归
WITH cte (OLD, NEW, lev)
AS (SELECT OLD, NEW, 1 AS lev FROM mytable
UNION ALL
SELECT m.old, cte.new, cte.lev + 1
FROM mytable m JOIN cte ON cte.old = m.new
)
CYCLE OLD SET cycle TO 1 DEFAULT 0
SELECT OLD, MAX (NEW) KEEP (DENSE_RANK LAST ORDER BY lev)
FROM cte
GROUP BY OLD
ORDER BY OLD;
这是我之前问题的后续问题:
假设我有这个数据集
| old | new |
|------|-------|
| a | b |
| b | c |
| d | e |
| e | a | <- Here is a cycle
| ... | ... |
| aa | bb |
| bb | ff |
| ... | ... |
| 11 | 33 |
| 33 | 523 |
| 523 | 4444 |
| 4444 | 33 | <- another cycle
因为循环oracle returns这个错误: "ORA-32044: cycle detected while executing recursive WITH query"
我想打破递归循环并检测导致循环的行
下面可以用“<”打破循环
with numbers(val) as (
select 1 as val from dual
union all
select val + 1 from numbers
where val < 5
)
select val from numbers
我尝试了以下方法:http://rextester.com/ITB3407
相同的代码:
with cte (old, new, lev) as
(
select old, new, 1 as lev from mytable
union all
select m.old, cte.new, cte.lev + 1
from mytable m
join cte on cte.old = m.new
where cte.lev < 6
)
select old, max(new) keep (dense_rank last order by lev) as new
from cte
group by old
order by old;
添加 CYCLE
子句。通过指定此子句,检测到循环并停止递归
WITH cte (OLD, NEW, lev)
AS (SELECT OLD, NEW, 1 AS lev FROM mytable
UNION ALL
SELECT m.old, cte.new, cte.lev + 1
FROM mytable m JOIN cte ON cte.old = m.new
)
CYCLE OLD SET cycle TO 1 DEFAULT 0
SELECT OLD, MAX (NEW) KEEP (DENSE_RANK LAST ORDER BY lev)
FROM cte
GROUP BY OLD
ORDER BY OLD;