For a solution that works for a finite "maximum" depth, you can use a query like this:
SELECT CASE
WHEN MAX(l8.category_id IS NOT NULL) THEN 8
WHEN MAX(l7.category_id IS NOT NULL) THEN 7
WHEN MAX(l6.category_id IS NOT NULL) THEN 6
WHEN MAX(l5.category_id IS NOT NULL) THEN 5
WHEN MAX(l4.category_id IS NOT NULL) THEN 4
WHEN MAX(l3.category_id IS NOT NULL) THEN 3
WHEN MAX(l2.category_id IS NOT NULL) THEN 2
WHEN MAX(l1.category_id IS NOT NULL) THEN 1
ELSE 0
END AS max_depth
FROM category l1
LEFT JOIN category l2 ON l2.parent = l1.category_id
LEFT JOIN category l3 ON l3.parent = l2.category_id
LEFT JOIN category l4 ON l4.parent = l3.category_id
LEFT JOIN category l5 ON l5.parent = l4.category_id
LEFT JOIN category l6 ON l6.parent = l5.category_id
LEFT JOIN category l7 ON l7.parent = l6.category_id
LEFT JOIN category l8 ON l8.parent = l7.category_id
WHERE l1.parent IS NULL
In this case, if the "tree" is more than eight levels deep, the query will return 8, the maximum depth it checks for.
This could be extended, but this approach requires some finite maximum. (MySQL has a limit on the number of table references in a query).
The "root" node of the tree will have a NULL value for parent. So, that's the node at level 1. (There could be multiple rows with a NULL value, multiple roots. (I' choosing to identify a one level tree with a max depth of 1, and choosing to return 0 if there are no "root" node(s).
The expression ln.category_id IS NOT NULL
will return a 1 if it's true, and 0 if it's false. If there's any row where it's a non-null value, we know the tree is at least that many levels deep.
The CASE expression is basically checking: is the tree at least 8 levels deep? If yes, we're done. If not, is the tree at least 7 levels deep? If not, is it at least 6 levels deep? etc.
If you remove that CASE wrapper expression, and the MAX
aggregates, what you get back is each node in the tree, and it's path back to the root node. You might want to order those from top down... level 1, level 2, level 3, etc.
For checking the maximum depth of the tree, we want to check from the bottom up.
To check for some unbounded depth, you'd need recursion, and MySQL doesn't support anything like that in the context of a SQL statement. You'd be into the realm of a MySQL stored program (procedure or function) to get a recursive solution.
(Other databases give us a convenient CONNECT BY
syntax. But alas, MySQL doesn't.)