Basierend auf der Antwort von @trincot, sehr gut erklärt, verwende ich die WITH RECURSIVE ()
-Anweisung, um ein Breadcrumb zu erstellen, das die id
der aktuellen Seite verwendet und rückwärts in der Hierarchie geht, um jedes parent
in meiner route
-Tabelle zu finden.
Also ist die Lösung von @trincot hier in die entgegengesetzte Richtung angepasst, um Eltern anstelle von Nachkommen zu finden.
Ich habe auch den Wert depth
hinzugefügt, der nützlich ist, um die Reihenfolge der Ergebnisse umzukehren (ansonsten wäre das Breadcrumb verkehrt herum).
WITH RECURSIVE cte (
`id`,
`title`,
`url`,
`icon`,
`class`,
`parent_id`,
`depth`
) AS (
SELECT
`id`,
`title`,
`url`,
`icon`,
`class`,
`parent_id`,
1 AS `depth`
FROM `route`
WHERE `id` = :id
UNION ALL
SELECT
P.`id`,
P.`title`,
P.`url`,
P.`icon`,
P.`class`,
P.`parent_id`,
`depth` + 1
FROM `route` P
INNER JOIN cte
ON P.`id` = cte.`parent_id`
)
SELECT * FROM cte ORDER BY `depth` DESC;
Vor dem Upgrade auf mySQL 8+ habe ich Vars verwendet, aber sie sind veraltet und funktionieren nicht mehr in meiner Version 8.0.22!
EDIT 2021-02-19: Beispiel für hierarchisches Menü
Nach dem Kommentar von @david habe ich beschlossen, zu versuchen, ein vollständiges hierarchisches Menü mit allen Knoten zu erstellen und so zu sortieren, wie ich es möchte (mit der sorting
-Spalte, die Elemente in jeder Ebene sortiert). Sehr nützlich für meine Benutzer-/Authorisierungsmatrix-Seite.
Dies vereinfacht wirklich meine alte Version mit einer Abfrage auf jeder Ebene (PHP-Schleifen).
Dieses Beispiel integriert ein INNER JOIN mit der url
-Tabelle, um Routen nach Website zu filtern (Mehrfach-Websites-CMS-System).
Sie können die wesentliche path
-Spalte sehen, die die CONCAT()
-Funktion enthält, um das Menü auf die richtige Weise zu sortieren.
SELECT R.* FROM (
WITH RECURSIVE cte (
`id`,
`title`,
`url`,
`icon`,
`class`,
`parent`,
`depth`,
`sorting`,
`path`
) AS (
SELECT
`id`,
`title`,
`url`,
`icon`,
`class`,
`parent`,
1 AS `depth`,
`sorting`,
CONCAT(`sorting`, ' ', `title`) AS `path`
FROM `route`
WHERE `parent` = 0
UNION ALL SELECT
D.`id`,
D.`title`,
D.`url`,
D.`icon`,
D.`class`,
D.`parent`,
`depth` + 1,
D.`sorting`,
CONCAT(cte.`path`, ' > ', D.`sorting`, ' ', D.`title`)
FROM `route` D
INNER JOIN cte
ON cte.`id` = D.`parent`
)
SELECT * FROM cte
) R
INNER JOIN `url` U
ON R.`id` = U.`route_id`
AND U.`site_id` = 1
ORDER BY `path` ASC