PostgreSQL 14
Assume I have the following table:
CREATE TABLE links
(
linkid serial primary key,
patientid integer NOT NULL,
linkto integer NOT NULL
)
INSERT INTO links (patientid, linkto)
VALUES (1,2), (1,3), (1,4), (1,5), (1,6);
INSERT INTO links (patientid, linkto)
VALUES (2,7), (2,8), (2,9), (2,10), (2,11);
INSERT INTO links (patientid, linkto)
VALUES (3,12), (3,13), (3,14), (3,15), (3,16);
INSERT INTO links (patientid, linkto)
VALUES (4,17), (4,18), (4,19), (4,20), (4,21);
Each patientid has multiple links. If I start with patientId of 1, the following will correctly enumerate all the id's 1 is directly related to AND all the id's that are linked to 1.
WITH RECURSIVE _IN (patientid) AS (
VALUES (1)
),
linked (linkid, patientid, linkto) AS (
SELECT k.linkid, k.patientid, k.linkto
FROM _IN n
JOIN links k ON k.patientid = n.patientid
UNION ALL
SELECT LL.linkid, LL.patientid, LL.linkto FROM linked L
INNER JOIN links LL ON L.linkto = LL.patientid
) SELECT * FROM linked
However, it will be quite possible that an id other than 1 will be given, e.g. "2".
In the case of "2", I want to enumerate all the id's 2 is related to (in a forward direction) as above, but ALSO enumerate all the id's linked to 2 in a backward direction. That is, as above, as 1 is a patient id, it is linked to 2. So if given 2, I need it to read backward to hit #1.
Additionally, each backlink will have its own set of links that need to be enumerated.
The following fails--and never completes. How can this be done?
WITH RECURSIVE _IN (patientid) AS (
VALUES (2)
),
linked (linkid, patientid, linkto) AS (
SELECT k.linkid, k.patientid, k.linkto
FROM _IN n
JOIN links k ON k.patientid = n.patientid
UNION ALL
SELECT LL.linkid, LL.patientid, LL.linkto FROM linked L
INNER JOIN links LL ON L.linkto = LL.patientid
),
backlink (linkid, patientid, linkto) AS (
SELECT k.linkid, k.patientid, k.linkto
FROM linked lll
JOIN links k ON k.linkto = lll.linkto
UNION ALL
SELECT LL.linkid, LL.linkto, LL.patientid FROM backlink L
INNER JOIN links LL ON L.linkto = L.linkto
)
SELECT * FROM backlink
Any help with this would be most appreciated.
TIA