MySQL: Find top/ultimate parent

青春壹個敷衍的年華 提交于 2019-12-20 07:53:19

问题


I've found a few things similar but nothing quite what I need.

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

I have a table that looks like the below and need to find the top-most parent using MySQL. The trouble I'm having in this is that there could be up to 20 in the heirarchy steps to get to the top parent and I think I'm just not well versed enough in MySQL to figure it out.

Thanks in advance!


回答1:


Here is an answer from me. Its not nice, but it works. the first query is for MariaDB with the sequence Engine and the longer is fron "normal" MySQL

The start Parameter (id) must set @sid := 8 here

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;

Samples

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 []>

I hope it helps you a little bit.



来源:https://stackoverflow.com/questions/36457611/mysql-find-top-ultimate-parent

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!