Last active
May 30, 2022 16:00
-
-
Save thebearingedge/17cf14d8880657becd3eb01f3cf031c2 to your computer and use it in GitHub Desktop.
recursive common table expression comment threads
This file contains 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
create table "users" ( | |
"userId" serial, | |
"username" text not null, | |
primary key ("userId") | |
); | |
create table "comments" ( | |
"commentId" serial, | |
"userId" integer not null, | |
"content" text not null, | |
"replyingTo" integer, | |
primary key ("commentId"), | |
foreign key ("replyingTo") | |
references "comments" ("commentId") | |
); | |
insert into "users" ("username") | |
values ('thebearingedge'), ('timelikeclosure'), ('codingcodymiller'), ('scbowler'); | |
insert into "comments" ("userId", "content") | |
values (1, 'this is cool'), (2, 'this is great'), (3, 'this is nice'), (4, 'this is awesome'); | |
insert into "comments" ("userId", "content", "replyingTo") | |
values (1, 'you are nice', 3); | |
with recursive "thread" ("commentId", "userId", "content", "replyingTo", "replies") as ( | |
select "c".*, | |
'[]'::json | |
from "comments" as "c" | |
where not exists ( | |
select true | |
from "comments" as "r" | |
where "r"."replyingTo" = "c"."commentId" | |
) | |
union all | |
select ("c").*, | |
json_agg("r") as "replies" | |
from ( | |
select "c", | |
"r" | |
from "thread" as "r" | |
join "comments" as "c" | |
on "c"."commentId" = "r"."replyingTo" | |
) as "commentThread" | |
group by "commentThread"."c" | |
) | |
select json_agg("t") as "threads" | |
from "thread" as "t" | |
left join "comments" as "c" | |
on "c"."commentId" = "t"."replyingTo" | |
where "c"."commentId" is null; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Lifted from a few Stackoverflow posts and this sandbox. Here is the result.