我在尝试对 Laravel 项目中的评论和回复(无限嵌套级别)进行排序时遇到麻烦。
我的表
comments
具有类似的结构(简化):
id
| body
| user_id
| parent_id
| commentable_id
| created_at
(根)注释的
parent_id
具有 NULL 值。
单页评论和回复数量(commentable_id
)可能会超过500条。
我希望能够对评论进行排序
created_at
DESC,但回复的树形结构应该保留。
到现在为止我有这个疑问:
WITH RECURSIVE child_comments (id, body, parent_id, created_at, path, depth) AS
(
SELECT id, body, parent_id, created_at,
CAST(id AS CHAR(200)),
0 as depth
FROM comments
WHERE
commentable_id = 150
AND parent_id is NULL
UNION ALL
SELECT c.id, c.body, c.parent_id, c.created_at,
CONCAT(cc.path, ', ', c.id),
cc.depth + 1
FROM child_comments cc
JOIN comments c ON c.parent_id =cc.id
WHERE c.commentable_id = 150
) SELECT * from child_comments
ORDER BY
CASE WHEN parent_id != 0 THEN path END,
CASE WHEN parent_id is NULL THEN `created_at` END DESC;
结果是这样的:
+------+------------------+-----------+---------------------+---------------+-------+
| id | body | parent_id | created_at | path | depth |
+------+------------------+-----------+---------------------+---------------+-------+
| 7 | coment 3 | NULL | 2024-05-09 12:13:07 | 7 | 0 |
| 2 | coment 2 | NULL | 2024-05-02 21:07:29 | 2 | 0 |
| 1 | coment 1 | NULL | 2024-05-02 17:28:42 | 1 | 0 |
| 3 | coment 1_1 | 1 | 2024-05-07 23:02:50 | 1, 3 | 1 |
| 5 | coment 1_1_1 | 3 | 2024-05-07 23:03:02 | 1, 3, 5 | 2 |
| 6 | coment 1_1_1_1 | 5 | 2024-05-07 23:05:26 | 1, 3, 5, 6 | 3 |
| 9 | coment 1_1_1_1_1 | 6 | 2024-05-09 12:14:06 | 1, 3, 5, 6, 9 | 4 |
| 4 | coment 1_2 | 1 | 2024-05-07 23:02:57 | 1, 4 | 1 |
| 8 | coment 2_1 | 2 | 2024-05-09 12:13:35 | 2, 8 | 1 |
+------+------------------+-----------+---------------------+---------------+-------+
但我想要这样的结果:
+----+-------------------+-----------+---------------------+---------------+-------+
| id | body | parent_id | created_at | path | depth |
+----+-------------------+-----------+---------------------+---------------+-------+
| 7 | comment 3 | NULL | 2024-05-09 12:13:07 | 7 | 0 |
| 2 | comment 2 | NULL | 2024-05-02 21:07:29 | 2 | 0 |
| 8 | comment 2_1 | 2 | 2024-05-09 12:13:35 | 2, 8 | 1 |
| 1 | comment 1 | NULL | 2024-05-02 17:28:42 | 1 | 0 |
| 3 | comment 1_1 | 1 | 2024-05-07 23:02:50 | 1, 3 | 1 |
| 5 | comment 1_1_1 | 3 | 2024-05-07 23:03:02 | 1, 3, 5 | 2 |
| 6 | comment 1_1_1_1 | 5 | 2024-05-07 23:05:26 | 1, 3, 5, 6 | 3 |
| 9 | comment 1_1_1_1_1 | 6 | 2024-05-09 12:14:06 | 1, 3, 5, 6, 9 | 4 |
| 4 | comment 1_2 | 1 | 2024-05-07 23:02:57 | 1, 4 | 1 |
+----+-------------------+-----------+---------------------+---------------+-------+
有什么建议吗?
您可以在初始选择中添加
thread_created_at
并坚持所有子评论:
WITH RECURSIVE child_comments (id, body, parent_id, created_at, thread_created_at, path, depth) AS
(
SELECT id, body, parent_id, created_at, created_at,
CAST(id AS CHAR(200)),
0
FROM comments
WHERE
commentable_id = 150
AND parent_id IS NULL
UNION ALL
SELECT c.id, c.body, c.parent_id, c.created_at, cc.thread_created_at,
CONCAT(cc.path, ', ', c.id),
cc.depth + 1
FROM child_comments cc
JOIN comments c ON c.parent_id = cc.id
WHERE c.commentable_id = 150
)
SELECT * FROM child_comments
ORDER BY thread_created_at DESC, path ASC;
这是一个db<>小提琴。