MySQL 根据下一个和上一个项目查询订单项目

MySQL query order items based on next and previous item

我有 table 个使用以下 SQL 代码创建的项目。

CREATE TABLE `items` (
    `id` INT (11) NOT NULL AUTO_INCREMENT
    ,`Contents` VARCHAR(256) NOT NULL
    ,`Set` INT (11) DEFAULT NULL
    ,`Nxt` INT (11) DEFAULT NULL
    ,`Prev` INT (11) DEFAULT NULL
    ,PRIMARY KEY (`id`)
    ,KEY `Nxt`(`Prev`)
    ,KEY `Prev`(`Nxt`)
    ,CONSTRAINT `items_ibfk_1` FOREIGN KEY (`Nxt`) REFERENCES `items`(`id`)
    ,CONSTRAINT `items_ibfk_2` FOREIGN KEY (`Prev`) REFERENCES `items`(`id`)
    ) ENGINE = InnoDB DEFAULT CHARSET = utf8;

如您所见,每个项目都引用了它的上一个和下一个项目,它也相关,我在其中有以下数据。

Id      Contents    Set     Prev        Nxt
1       dakhd       1       NULL        4
2       234         2       7           6
3       fwer4w5     1       4           8
4       f34w5       1       1           3
5       234d233     2       NULL        7
6       1234        2       2           NULL
7       324         2       5           2
8       qw4         1       3           NULL

我如何编写一个查询,以便按 Set 对它们进行排序,然后取 Prev 列中为 NULL 的项目,然后取下一个项目中的每一个示例:

Id      Contents    Set     Prev        Nxt
1       dakhd       1       NULL        4
4       f34w5       1       1           3
3       fwer4w5     1       4           8
8       qw4         1       3           NULL
5       234d233     2       NULL        7
7       324         2       5           2
2       234         2       7           6
6       1234        2       2           NULL

我有以下查询,将按这些查询进行排序。设置列但是我不确定从哪里开始订购项目

select * from `items` order by `Set`;

我认为您确实需要为此进行递归查询:

with recursive cte as (
    select i.*, 1 lvl from items where prev is null
    union all
    select i.*, c.lvl + 1
    from cte c
    inner join items i on i.prev = c.id
)
select * from cte order by set, lvl

with 子句选择每个 set 中的“第一个”项(由 prev 中的 null 值指定),然后遍历依赖树,同时保持更新代表每个节点深度的计数器。然后您可以使用该信息对结果集进行排序。

请注意,递归查询仅在 MySQL 8.0 中可用。

您可以使用 case when,假设 id 始终大于 0,则以下应该有效:

select * 
from `items` 
order by `Set`
,case when `Prev` is null then -1 when `Nxt` is null then 1000000 else `Nxt` end
;