Last active
October 10, 2022 20:34
-
-
Save bchapuis/2ec695cf23fdc7e378e14f520b8c0986 to your computer and use it in GitHub Desktop.
Demonstrates the use of a recursive CTE to find the neighbors of a vertex through its edges in a PostgreSQL database.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- https://www.postgresql.org/docs/current/queries-with.html | |
DROP TABLE IF EXISTS vertex; | |
DROP TABLE IF EXISTS edge; | |
CREATE TABLE IF NOT EXISTS vertex ( | |
id int primary key | |
); | |
CREATE TABLE IF NOT EXISTS edge ( | |
source int, | |
target int, | |
primary key (source, target), | |
-- prevent duplicates and self-loop | |
check ( source < target ) | |
); | |
INSERT INTO vertex (id) VALUES (1); | |
INSERT INTO vertex (id) VALUES (2); | |
INSERT INTO vertex (id) VALUES (3); | |
INSERT INTO vertex (id) VALUES (4); | |
INSERT INTO vertex (id) VALUES (5); | |
INSERT INTO vertex (id) VALUES (6); | |
INSERT INTO edge (source, target) VALUES (1,2); | |
INSERT INTO edge (source, target) VALUES (2,3); | |
INSERT INTO edge (source, target) VALUES (3,4); | |
INSERT INTO edge (source, target) VALUES (4,5); | |
INSERT INTO edge (source, target) VALUES (5,6); | |
-- select the neighbors with breadth-first search | |
WITH RECURSIVE neighbors(id, source, target, depth, is_cycle, path) AS ( | |
SELECT v.id, e.source, e.target, 3, false, ARRAY[v.id] | |
FROM vertex v | |
INNER JOIN edge e ON v.id IN (e.source, e.target) | |
WHERE v.id = 3 | |
UNION ALL | |
SELECT v.id, e.source, e.target, n.depth - 1, v.id = ANY(path), path || v.id | |
FROM vertex v | |
INNER JOIN edge e ON v.id IN(e.source, e.target) | |
INNER JOIN neighbors n ON v.id IN (n.source, n.target) | |
WHERE n.depth > 0 AND NOT n.is_cycle | |
) | |
SELECT * | |
FROM neighbors n | |
WHERE NOT n.is_cycle | |
ORDER BY n.depth DESC |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment