我有一张表:
+------+---------+-
| id | parent |
+------+---------+
| 2043 | NULL |
| 2044 | 2043 |
| 2045 | 2043 |
| 2049 | 2043 |
| 2047 | NULL |
| 2048 | 2047 |
| 2043 | 2047 |
+------+---------+
显示了一个简单的2级“父子” - 核心。我怎样才能通过SELECT语句来获取上面列表中的顺序,这意味着:第一个父项,第一个父项的子项,第二个父项,第二个父项的子项等等(如果我有,我可以添加为孩子们订购BY ...我希望)。是否可以添加排序字段?
答案 0 :(得分:52)
包括按id:
对儿童进行排序ORDER BY COALESCE(parent, id), parent IS NOT NULL, id
说明:
COALESCE(parent, id)
:首先按父母的身份(有效地分组)排序。parent IS NOT NULL
:将父行放在群组id
:最后对所有孩子进行排序(同一个父级,parent
不为空)答案 1 :(得分:1)
如果您的表使用0
而不是null
来表示没有父级的条目:
id | parent
-------------
1233 | 0
1234 | 1233
1235 | 0
1236 | 1233
1237 | 1235
使用greatest
代替coalesce
并检查值是否等于0
:
ORDER BY GREATEST(parent, id), parent != 0, id
答案 2 :(得分:0)
上面的解决方案对我不起作用,我的表使用0而不是NULL。 我找到了另一个解决方案:在查询中创建一个带有连接父ID和子ID的列,您可以按它对结果进行排序。
SELECT CONCAT(IF(parent = 0,'',CONCAT('/',parent)),'/',id) AS gen_order
FROM table
ORDER BY gen_order
答案 3 :(得分:0)
此问题仍显示为第一个搜索结果。所以我想分享一个我的解决方案,希望它能帮助更多的人。当您的表具有多个级别的父子关系时,这也将起作用。虽然这是一个很慢的解决方案。顶层有 NULL
作为父级。
+---------+---------+
| id | parent |
+---------+---------+
| 1 | NULL |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
+---------+---------+
在我的方法中,我将使用一个过程,该过程将递归调用自身,并继续在路径前面加上请求的 id
的父级,直到它到达 NULL
父级。
DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `PATH`(IN `input` INT, OUT `output` VARCHAR(128))
BEGIN
DECLARE _id INT;
DECLARE _parent INT;
DECLARE _path VARCHAR(128);
SET `max_sp_recursion_depth` = 50;
SELECT `id`, `parent`
INTO _id, _parent
FROM `database`.`table`
WHERE `table`.`id` = `input`;
IF _parent IS NULL THEN
SET _path = _id;
ELSE
CALL `PATH`(_parent, _path);
SELECT CONCAT(_path, '-', _id) INTO _path;
END IF;
SELECT _path INTO `output`;
END $$
DELIMITER ;
要在 ORDER BY
子句中使用结果,您还需要一个 FUNCTION
来包装 PROCEDURE
的结果。
DELIMITER $$
CREATE DEFINER=`root`@`localhost` FUNCTION `GETPATH`(`input` INT) RETURNS VARCHAR(128)
BEGIN
CALL `PATH`(`input`, @path);
RETURN @path;
END $$
DELIMITER ;
现在我们可以使用递归路径对表格进行排序。在一个有 10000 行的表上,在我的工作站上只需要一秒钟多。
SELECT `id`, `parent`, GETPATH(`id`) `path` FROM `database`.`table` ORDER BY `GETPATH`(`id`);
示例输出:
+---------+---------+---------------+
| id | parent | path |
+---------+---------+---------------+
| 1 | NULL | 1 |
| 10 | 1 | 1-10 |
| 300 | 10 | 1-10-300 |
| 301 | 300 | 1-10-300-301 |
| 302 | 300 | 1-10-300-302 |
+---------+---------+---------------+
5 rows in set (1,39 sec)