User Tools

Site Tools


mysql:adjacencytree:pathlistperid

Adjacency Tree: Einfache Pfad-Liste für eine id

Aufgabenstellung

Als erstes will ich eine einfache Auflistung eines Pfades für einen bestimmten Eintrag. Ich nehme mal die 9 Als Startpunkt. Nun soll mir mein SQL-Script alle folgenden Nodes des Pfade ausgeben. Also die 1 (Root), dann 2 etc. bis zur 9.

Beispiel bei SQLFiddle

SQL Statement

SELECT
	nav.id,
	nav.title
FROM
	(
		SELECT  
			@cnt := @cnt + 1 AS cnt,
			-- Die letzte ParentID als ID ausgeben
			@id AS id,
			-- Die nächste ParentID ermitteln
			@id := IF(@id IS NOT NULL, (SELECT parentID FROM nav WHERE id = @id), NULL) AS parentID
		FROM
			nav,
			-- Die Variablen initialisieren
			-- TODO: Hier anstelle der 9 deine Start-ID setzen
			(SELECT @id := 9, @cnt:= 0) AS vars
		WHERE
			@id IS NOT NULL
	) AS dat
	-- Das ganze mit der Navigationstabelle verlinken on den Titel 
	-- und ggf. weitere Informationen auszulesen
	 INNER JOIN nav
		ON dat.id = nav.id
ORDER BY
	cnt;

Ausgabe

id title
1 Node #001
2 Node #002
8 Node #008
10 Node #010
9 Node #009

Erklärbär

So, dann versuch ich mal das ganze zu erklären. Denn nur Code kopieren und nicht verstehen bringt ja nicht wirklich viel.

Variablen setzen

Als erstes werden die MySQL-Variablen definiert. Ganz wichtig. Hier wird auch die Start-Id gesetzt. In unserem Beispiel also die 9. cnt ist nix weiteres als ein Counter/Zeilennumer

vars
-- [VARS]
			-- Die Variablen initialisieren
			-- TODO: Hier anstelle der 9 deine Start-ID setzen
			(SELECT @id := 9, @cnt:= 0) AS vars

Den Baum durchiterieren

Dann kommt der lustige Teil. Ich nehme die Tabelle nav in den FROM-Teil meines QUeries. Jedoch ist sie an dieser Stelle blos ein Platzhalter der mir die nötige Anzahl Zeilen liefert. Der Rest wird fortlaufend berechnet.

Grid
-- [GRID]
		SELECT  
			@cnt := @cnt + 1 AS cnt,
			-- Die letzte ParentID als ID ausgeben
			@id AS id,
			-- Die nächste ParentID ermitteln
			@id := (SELECT parentID FROM nav WHERE id = @id) AS parentID
		FROM
			nav,
			[VARS]
		WHERE
			@id IS NOT NULL

Also, was passiert hier. Stellen wir uns das ganze wie ein Excel-Sheet vor.die Tabelle nav des FROM-Bloacks ist nur das Grid. Als erstes geben wir die aktulle id (Variable @id) in der Spalte `id` aus: ##@id AS id## Als nächstes ermitteln die parentID zur id: ##(SELECT parentID FROM nav WHERE id = @id)##. Das geben wir auch in der Spalte `parentid` aus. Zugleich überschreiben wir aber die Variable @id mit dieser parentid. Somit ist für die nächste Zeile die parentid der Vorzeile die id. Mit dieser neuen id geht das Spiel wieder von vorne los. Nun habe ich geschrieben, die Tabelle nav dient uns als Grid. Das Grid ist natürlich viel zu gross. Wenn wir den Root des Trees erreichthaben, wird die parentid (und somit nachher auch die id) mit NULL abgefüllt. Ergo filtern wir am Schluss alle NULL noch aus: ##WHERE @id IS NOT NULL ##

Im Originalbeispiel findet ihr noch die Zeile ##@rownum := @rownum+1 AS rownum,##. Hier wird einfach fortlaufend durchnumeriert um eine Zeilennummer zu haben.

Infos Ergänzen und neu sortieren

Zum Schluss habe ich mein Resultat noch in eine weitere SELECT Abfrage gepackt.

SELECT
	nav.id,
	nav.title
FROM
	(
		[GRID]
	) AS grid
	-- Das ganze mit der Navigationstabelle verlinken on den Titel 
	-- und ggf. weitere Informationen auszulesen
	INNER JOIN nav
		ON grid.id = nav.id
ORDER BY 
	cntDESC

Als erstes verknüpfe ich nun mein Grid mit der Tabelle nav. So kann ich zu jedem Node die Details mit auslesen. Je nachdem was da alles definiert ist (Titel, URL, Tooltiptext etc). In meinem Fall ist das das Feld `title`. Zudem sortiere ich nun das ganze um, so dass mein Root-Eintrag als erstes erscheint. Dann Der Ordner auf Level 1 etc.


Weiter gehts mit Adjacency Tree: Pfad pro id

mysql/adjacencytree/pathlistperid.txt · Last modified: 12.03.2014 10:58:38 (external edit)