在其上运行此查询的表的 struct 大致如下:

comments_table(PK id, FK reply_to_id, content) 

FK is a self join on itself

它在10.4.27上运行-MariaDB

数据如下所示:

+----+-------------+---------+
| id | reply_to_id | content |
+----+-------------+---------+
| 12 |     NULL    |   text  |
| 13 |      12     |   text  |
| 14 |      12     |   text  |
| 15 |      13     |   text  |
+----+-------------+---------+

该查询应该按顺序检索输入父项(或树根)中给出的所有回复注释.

结果顺序应该是深度优先.

预期结果的一个示例:

Input : 12
Result: 13,15,14

    12
  /    \
13      14
  \
   15
+----+
| id |
|----+
| 13 |
| 15 |
| 14 |
+----+

诸若此类

我try 存档的是在不使用任何外部代码的情况下在查询中完成此操作.

我一直在try 递归并修改如下所示的查询:

select id 
from (
    select * from comments order by id
) comments_sorted, (
    select @pv := '62'
) initialisation 
where find_in_set(replied_to_id, @pv)
and length(@pv := concat(@pv, ',', id));

query does work,它在输出中给出对给定父亲(或树根)的所有回复

输出如下所示:

+----+
| id |
+----+
| 13 |
| 14 |
| 15 |
+----+

同时,所需的输出如上图所示

它怎么可能实现呢?

EDIT

提供其他反馈

使用带有以下数据集的查询@luuk:

+----+---------------+
| id | replied_to_id |
+----+---------------+
| 81 |          NULL |
| 82 |          NULL |
| 83 |            82 |
| 84 |            83 |
| 85 |            83 |
| 86 |            83 |
| 87 |            84 |
| 88 |            87 |
| 93 |            88 |
+----+---------------+

我得到的结果是:

+---+----+---------------+
| x | id | replied_to_id |
+---+----+---------------+
| 1 | 83 |            82 |
| 1 | 84 |            83 |
| 1 | 85 |            83 |
| 1 | 86 |            83 |
| 1 | 87 |            84 |
| 1 | 88 |            87 |
| 1 | 93 |            88 |
+---+----+---------------+

我可以看到x值没有递增.

我使用的查询是:

WITH RECURSIVE cte AS ( 
   SELECT row_number() over (order by id) as x, id, replied_to_id 
   FROM comments 
   WHERE replied_to_id=82 
   UNION ALL 
   SELECT x, comments.id, comments.replied_to_id 
   FROM cte 
   INNER JOIN comments on comments.replied_to_id = cte.id 
) 
SELECT * FROM cte ORDER BY x,id;

会是什么呢?

推荐答案

以下是另一种方法,使用数据订购路径:

WITH recursive cte (id, reply_to_id, path)
AS
(
    SELECT id, reply_to_id, CAST(id AS CHAR(200)) AS path
    FROM comments_table
    WHERE reply_to_id = 12
  UNION ALL
    SELECT e.id, e.reply_to_id, CONCAT(cte.path, ",", e.id)
    FROM comments_table AS e
    JOIN cte ON e.reply_to_id = cte.id
)
SELECT *
from cte
order by path

Demo here

Sql相关问答推荐

Oracle中的分层查询

如何退回当年的所有参赛作品?""

在postgres中动态计算出现次数并插入到json中

带日期函数的复合索引不允许只扫描索引吗?

Oracle PL/SQL:解决DBMS输出大小限制的问题

优化Postgres搜索未知长度的子串

按用户和时间列出的SQL Group考勤列表

如何将insert语句重复n次使一个值递增?

SQL查询正在工作,但返回空结果

无法访问级联删除导致的触发器中已删除的外键记录

Grafana SQL 模板变量(值、文本)

使用多个数据库调用重载 CQRS 模式

避免在SQL中使用具有相同条件的多个子查询

PostgreSQL如何将Unix纪元时间戳转换为日期时间并进行拼接

SQL Server 查找存在于所有不同时期(或序列)中的条目

Oracle SQL 从多个条件中 Select 但具有相同的 id

PostgresQL-根据另一列找到 3 个最低值

如何在一个存储过程中创建全局临时表,并在另一个存储过程中使用它

在 Athena / Presto 中提取 JSON 对象以获取动态密钥

SQL/Postgres:按日期和其他属性对相关性能进行分组