在一个SQL查询中获取所有父行

Ale*_*lex 24 mysql sql hierarchical-data

我有一个简单的MySQL表,其中包含一个类别列表,级别由parent_id确定:

id  name    parent_id
---------------------------
1   Home        0
2   About       1
3   Contact     1
4   Legal       2
5   Privacy     4
6   Products    1
7   Support     1
Run Code Online (Sandbox Code Playgroud)

我正试图做一个面包屑的踪迹.所以我有孩子的'id',我想得到所有可用的父母(迭代链,直到我们达到0"Home").可以有任何数量或子行进入无限深度.

目前我正在为每个父级使用SQL调用,这很麻烦.SQL中是否有一种方法可以在一个查询中完成所有操作?

Mar*_*ers 59

摘自这里:

SELECT T2.id, T2.name
FROM (
    SELECT
        @r AS _id,
        (SELECT @r := parent_id FROM table1 WHERE id = _id) AS parent_id,
        @l := @l + 1 AS lvl
    FROM
        (SELECT @r := 5, @l := 0) vars,
        table1 h
    WHERE @r <> 0) T1
JOIN table1 T2
ON T1._id = T2.id
ORDER BY T1.lvl DESC
Run Code Online (Sandbox Code Playgroud)

该行@r := 5是当前页面的页码.结果如下:

1, 'Home'
2, 'About'
4, 'Legal'
5, 'Privacy'
Run Code Online (Sandbox Code Playgroud)

  • 你先生......是天才! (6认同)
  • 如果有人可以解释这个神奇的查询中发生的事情,那将是如此美好... (4认同)
  • 如何反向查询,即从父级获取所有子级? (2认同)

MaY*_*aNk 8

接受的答案具有递归检索子用户的所有父用户的最佳解决方案。我已根据我的需要对此进行了修改。

对于 MySQL 5.5、5.6 和 5.7

SELECT @r AS user_id, 
   (SELECT @r := parent_id FROM users_table WHERE id = user_id) AS parent_id, 
   @l := @l + 1 AS level 

   FROM (SELECT @r := 9, @l := 0) val, users_table WHERE @r <> 0 
Run Code Online (Sandbox Code Playgroud)

注意:@r := 9。其中 9 是子用户的 id。

请参阅此处的小提琴


上述查询在 MySQL 8 中已弃用。因此这是 MySQL 8.0 的查询

with recursive parent_users (id, parent_id, level) AS (
  SELECT id, parent_id, 1 level
  FROM users_table
  WHERE id = 9
  union all
  SELECT t.id, t.parent_id, level + 1
  FROM users_table t INNER JOIN parent_users pu
  ON t.id = pu.parent_id
)
SELECT * FROM parent_users;
Run Code Online (Sandbox Code Playgroud)

注意:id = 9。其中 9 是子用户的 id。

请参阅此处的小提琴