例 5.2. 话题讨论表的设计
http://justcramer.com/2010/05/30/scaling-threaded-comments-on-django-at-disqus/
create table comments (
id SERIAL PRIMARY KEY,
message VARCHAR,
author VARCHAR,
parent_id INTEGER REFERENCES comments(id)
);
insert into comments (message, author, parent_id)
values ('This thread is really cool!', 'David', NULL), ('Ya David, we love it!', 'Jason', 1), ('I agree David!', 'Daniel', 1), ('gift Jason', 'Anton', 2),
('Very interesting post!', 'thedz', NULL), ('You sir, are wrong', 'Chris', 5), ('Agreed', 'G', 5), ('Fo sho, Yall', 'Mac', 5);
WITH RECURSIVE cte (id, message, author, path, parent_id, depth) AS (
SELECT id,
message,
author,
array[id] AS path,
parent_id,
1 AS depth
FROM comments
WHERE parent_id IS NULL
UNION ALL
SELECT comments.id,
comments.message,
comments.author,
cte.path || comments.id,
comments.parent_id,
cte.depth + 1 AS depth
FROM comments
JOIN cte ON comments.parent_id = cte.id
)
SELECT id, message, author, path, depth FROM cte ORDER BY path;
输出结果
id | message | author | path | depth
----+-----------------------------+--------+---------+-------
1 | This thread is really cool! | David | {1} | 1
2 | Ya David, we love it! | Jason | {1,2} | 2
4 | gift Jason | Anton | {1,2,4} | 3
3 | I agree David! | Daniel | {1,3} | 2
5 | Very interesting post! | thedz | {5} | 1
6 | You sir, are wrong | Chris | {5,6} | 2
7 | Agreed | G | {5,7} | 2
8 | Fo sho, Yall | Mac | {5,8} | 2
(8 rows)