Skip to content

Instantly share code, notes, and snippets.

@swanandp
Last active November 29, 2023 17:23
Show Gist options
  • Save swanandp/ebc55ea0ba0364e137b6013c6eaedcbf to your computer and use it in GitHub Desktop.
Save swanandp/ebc55ea0ba0364e137b6013c6eaedcbf to your computer and use it in GitHub Desktop.
A demonstration of recursive query in SQL
CREATE TABLE posts
(
id bigserial PRIMARY KEY,
content text NOT NULL,
reply_to_id bigint REFERENCES posts (id)
);
TRUNCATE posts RESTART IDENTITY; -- this deletes all rows and restarts the auto-increment ID
/*
Let's create nested data like this:
-> R
-> R-O
-> R-O-A
-> R-O-A-D
-> R-O-D
-> R-A
-> R-A-P
-> S
-> H
*/
INSERT INTO posts(content)
VALUES ('R');
INSERT INTO posts(content, reply_to_id)
VALUES ('RO', 1),
('RA', 1);
INSERT INTO posts(content, reply_to_id)
VALUES ('ROA', 2),
('RAP', 3);
INSERT INTO posts(content, reply_to_id)
VALUES ('ROAD', 4);
INSERT INTO posts(content, reply_to_id)
VALUES ('ROD', 2);
INSERT INTO posts(content)
VALUES ('S');
INSERT INTO posts(content, reply_to_id)
VALUES ('SH', 7);
SELECT *
FROM posts;
-- select all children for 'R'
WITH RECURSIVE leaves(id, content, reply_to_id) AS
(SELECT id, content, reply_to_id
FROM posts
WHERE content = 'R'
UNION ALL
SELECT p.id, p.content, p.reply_to_id
FROM leaves l
INNER JOIN posts p ON l.id = p.reply_to_id)
SELECT *
FROM leaves;
-- select all children for 'S'
WITH RECURSIVE leaves(id, content, reply_to_id) AS
(SELECT id, content, reply_to_id
FROM posts
WHERE content = 'S'
UNION ALL
SELECT p.id, p.content, p.reply_to_id
FROM leaves l
INNER JOIN posts p ON l.id = p.reply_to_id)
SELECT *
FROM leaves;
-- select all children for 'RO'
WITH RECURSIVE leaves(id, content, reply_to_id) AS
(SELECT id, content, reply_to_id
FROM posts
WHERE content = 'RO'
UNION ALL
SELECT p.id, p.content, p.reply_to_id
FROM leaves l
INNER JOIN posts p ON l.id = p.reply_to_id)
SELECT *
FROM leaves;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment