MySQL:找到顶级/终极父级

时间:2016-04-06 16:58:46

标签: mysql parent

我发现了一些相似的东西,但没有什么我需要的东西。

ID  |   PARENT
1   |   NULL
2   |   5
3   |   6
4   |   6
5   |   NULL
6   |   9
7   |   NULL
8   |   7
9   |   8
10  |   NULL

我有一个如下所示的表,需要使用MySQL查找最顶层的父表。我在这方面遇到的麻烦是,在层次结构的步骤中最多可能有20个达到顶级父级,我认为我在MySQL中不够精通,无法弄明白。

提前致谢!

1 个答案:

答案 0 :(得分:0)

以下是我的回答。它不好,但它的工作原理。第一个查询是针对具有引擎序列的MariaDB,而较长的是“正常”MySQL

开始参数(id)必须在此设置 @sid:= 8

<强> MariaDB的

SELECT path, sid
FROM (
  SELECT *, @sid AS sid, @path := CONCAT(@path,' -> ', @sid) AS path,
  (SELECT (@sid:=parent) FROM mytab WHERE id = @sid) AS parent  
  FROM seq_1_to_99
  CROSS JOIN ( SELECT @sid := 8 , @path :=@sid) AS parameter
  HAVING parent = @sid
) AS result
ORDER BY seq DESC
LIMIT 1;

<强>的MySQL

SELECT path, sid FROM (
SELECT *, @sid AS sid,
 @path := CONCAT(@path,' -> ', @sid) AS PATH,
 (SELECT (@sid:=parent) FROM mytab WHERE id = @sid) AS parent

FROM (
  SELECT *
  FROM (
    SELECT d2.a*10+d1.a  AS nr
    FROM (
        SELECT 0 a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL
        SELECT 4   UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL
        SELECT 8   UNION ALL SELECT 9) AS d1
      CROSS JOIN (
        SELECT 0 a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3  ) AS d2
  ) AS counter
  ORDER BY counter.nr
) AS result
CROSS JOIN ( SELECT @sid := 8 , @path :=@sid) AS parameter
HAVING parent = @sid
) AS p
ORDER BY nr DESC
LIMIT 1;

<强>样品

MariaDB []> select * from mytab;
+----+--------+
| id | parent |
+----+--------+
|  1 |   NULL |
|  2 |      3 |
|  3 |   NULL |
|  4 |   NULL |
|  5 |      4 |
|  6 |      5 |
|  7 |      8 |
|  8 |      6 |
+----+--------+
8 rows in set (0.00 sec)

MariaDB []> SELECT path, sid
    -> FROM (
    ->   SELECT *, @sid AS sid, @path := CONCAT(@path,' -> ', @sid) AS path,
    ->   (SELECT (@sid:=parent) FROM mytab WHERE id = @sid) AS parent
    ->   FROM seq_1_to_99
    ->   CROSS JOIN ( SELECT @sid := 8 , @path :=@sid) AS parameter
    ->   HAVING parent = @sid
    -> ) AS result
    -> ORDER BY seq DESC
    -> LIMIT 1;
+-------------+------+
| path        | sid  |
+-------------+------+
| 8 -> 6 -> 4 | 4    |
+-------------+------+
1 row in set (0.01 sec)

MariaDB []> SELECT path, sid FROM (
    -> SELECT *, @sid AS sid,
    ->  @path := CONCAT(@path,' -> ', @sid) AS PATH,
    ->  (SELECT (@sid:=parent) FROM mytab WHERE id = @sid) AS parent
    ->
    -> FROM (
    ->   SELECT *
    ->   FROM (
    ->     SELECT d2.a*10+d1.a  AS nr
    ->     FROM (
    ->         SELECT 0 a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL
    ->         SELECT 4   UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL
    ->         SELECT 8   UNION ALL SELECT 9) AS d1
    ->       CROSS JOIN (
    ->         SELECT 0 a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3  ) AS d2
    ->   ) AS counter
    ->   ORDER BY counter.nr
    -> ) AS result
    -> CROSS JOIN ( SELECT @sid := 8 , @path :=@sid) AS parameter
    -> HAVING parent = @sid
    -> ) AS p
    -> ORDER BY nr DESC
    -> LIMIT 1;
+-------------+------+
| path        | sid  |
+-------------+------+
| 8 -> 6 -> 4 |    4 |
+-------------+------+
1 row in set (0.01 sec)

MariaDB []>

我希望它对你有所帮助。