问题
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