我想在表中找到链。 表X由3列组成
column1, column2, column3
wolf, eat, cat
cat, eat, mouse
我查询以查找“链”
SELECT t1.column1, t2.column3
FROM X AS t1
JOIN X AS t2
ON t1.column3 = t2.column1
我在这里有一条链子
wolf, eat, cat, cat, eat, mouse
然后我可以显示
wolf, mouse
但是对下一个数据的查询是什么?
column1, column2, column3
human, eat, bear
bear, eat, wolf
wolf, eat, cat
cat, eat, mouse
我想从列1中的任意生物开始,并在列3中找到链的末端,以检查X是否吃掉Y。
测试:
Show human->wolf
Show human->mouse
Show bear->mouse
我不知道如何在此处查找进行递归查询的步骤数。
答案 0 :(得分:0)
第二列与您的问题并不真正相关,因此可以归结为“标准”递归公用表表达式,其中“子”引用“父”行。
以下是标准ANSI SQL,您可能需要将其调整为实际使用的DBMS。
with recursive food_chain as (
select col1, col3, col1||' '||col2||' '||col3 as chain
from x
where col1 = 'human'
union all
select c.col1, c.col3, p.chain||', '||c.col1||' '||c.col2||' '||c.col3
from x as c
join food_chain p on c.col1 = p.col3
)
select *
from food_chain;
这将导致例如:
col1 | col3 | chain
------+-------+-----------------------------------------------------------
human | bear | human eat bear
bear | wolf | human eat bear, bear eat wolf
wolf | cat | human eat bear, bear eat wolf, wolf eat cat
cat | mouse | human eat bear, bear eat wolf, wolf eat cat, cat eat mouse
由于您仅对最后一个(最终)食物链感兴趣,因此可以通过添加一个标识级别的计数器并仅选择该级别来做到这一点
with recursive food_chain as (
select col1, col3, col1||' '||col2||' '||col3 as chain, 1 as level
from x
where col1 = 'human'
union all
select c.col1, c.col3, p.chain||', '||c.col1||' '||c.col2||' '||c.col3, p.level + 1
from x as c
join food_chain p on c.col1 = p.col3
)
select chain
from food_chain
order by level desc
fetch first 1 rows only
返回:
chain
----------------------------------------------------------
human eat bear, bear eat wolf, wolf eat cat, cat eat mouse
链条的起点由CTE的非递归部分中的条件定义:where col1 = 'human'
答案 1 :(得分:0)
如果您尝试在Oracle中执行此操作,则它具有很多内置功能,可以简化您的操作。
注意:我忽略了第二列eat
,因为它在这里是常量。
With hunt(predator, prey) as(
select 'human', 'bear' from dual union
select 'bear', 'wolf' from dual union
select 'wolf', 'cat' from dual union
select 'cat', 'mouse' from dual
)
select distinct * from (
SELECT connect_by_root predator as predator, prey
FROM hunt connect by predator = prior prey)
order by predator;
您的结果将如下所示: