i have two columns of numbers. the goal is starting from a number f.e. 55, to extract all ‘connected’ numbers (starting with any of those numbers, should yield the same result)
x
A B
-----
56 55
55 56
69 55
35 55
47 55
60 55
22 55
26 47
2 35
more data ..
in this case all numbers shown here : 55,56,35,69,60,22,47,2,26
I use the following query :
with recursive merge as (
select A from T where A = 55 or B = 55
union
select B
from T cm join merge m
on cm.A = m.A or cm.B = m.A
)
select * from merge
but I get back only those back : 55,56,35,69,60,22,47
I think using this will work :
with recursive merge as (
select A from T where A = 55 or B = 55
union
(
select B
from T cm join merge m
on cm.A = m.A
union
select A
from T cm join merge m
on cm.B = m.A
)
)
select * from merge
but Postgres does not allow to use “merge” more than ONCE in the recursive query !!?
My goal is starting with number to find all connected numbers across the “chain” i.e.
55 => 56,35,69,60,22,47 => 2,26 .
because :
47 => 26
35 => 2
Advertisement
Answer
You can do:
with recursive
n (v) as (
select case when t.a = 55 then t.b else t.a end
from t
where t.a = 55 or t.b = 55
union
select case when t.a = n.v then t.b else t.a end
from n
join t on t.a = n.v or t.b = n.v
)
select * from n
Result:
v
--
56
69
35
47
60
22
55
2
26
See running example at DB Fiddle.
Or… if you prefer to place the parameter in a single place:
with recursive
params as (select 55 as x), -- parameter only once
n (v) as (
select case when t.a = p.x then t.b else t.a end
from t
cross join params p
where t.a = p.x or t.b = p.x
union
select case when t.a = n.v then t.b else t.a end
from n
join t on t.a = n.v or t.b = n.v
)
select * from n