SQL Falsche Tiefe bei nested sets Abfrage

Eagle-PsyX-

Commander
Registriert
Juni 2006
Beiträge
2.246
Habe seit kurzem erst festgestellt, dass ich bei einer meiner Nesteds-Sets-Abfrage unlogische Tiefen zurückbekomme:

Code:
SELECT o.*,
     COUNT(p.category_id)-1 AS depth
FROM `blug_category` AS n,
     `blug_category` AS p,
     `blug_category` AS o
WHERE 
    o.category_left 
        BETWEEN p.category_left AND 
        p.category_right AND
            o.category_left 
        BETWEEN n.category_left AND 
        n.category_right
GROUP BY 
    o.category_left
ORDER BY 
    o.category_left
Interessanterweise sind die Teifen nach unten hin in der Reihenfolge immer: 0,3,8,15,24,35,48,63..

Will ich aber den unteren Stamm ausgehend von der id 3 wissen, also mit der WHERE-Bedinung n.category_id =3 kreige ich logische Tiefen raus: 0,1,2,3,4,..
Es ist ein Logik-Fehler irgendwie...Hat jemand Abhilfe?
Meine Zwischenlösung ist, dass ich die Reihenfolge als Array abgelegt habe und eine Verschiebung stattfindet, damit ich erkennen kann wer ein direktes "Kind" ist.
 

Anhänge

  • ergebnisse.png
    ergebnisse.png
    17 KB · Aufrufe: 178
Zuletzt bearbeitet:
beschreibe bitte erstmal das ziel anstelle des weges. dann kann man dir auch mit vertretbarem aufwand helfen.
 
Ein Order-By auf die Tiefe?!

Sorry für die blöde Antwort, aber mir ist auch die Problemstellung nicht ganz klar.
 
Nein nicht nach der Tiefe sortieren, dumm ausgedrückt. Die WERTE für Depth sind doch irgendwie unlogisch.
Schaut euch doch einmal bitte die Grafik an.

Die Tiefen haben einen seltsamen Wert. Wenn man sich die Bereiche anschaut und bedenkt, dass hier nach category_left sortiert wird, dann erwartet man für die Tiefen doch 0,1,0,1,2,3,2 und nicht wie im Bild 0,3,0,3,8,15,8

Experimentell habe ich mehr Verschachteln lassen und festgestellt:

Ziel-Wert | Ist-Wert
0 | 0
1 | 3
2 | 8
3 | 15
4 | 24
5 | 35
6 | 48
7 | 63
 
Zuletzt bearbeitet:
Hast du schon mal GROUP BY o.category_id probiert? Ich bin jetzt nicht so vertraut mit Nested Sets aber bei wikipedia wird da so gemacht :D
 
Nope. Hatte ich nicht macht auch keinen Sinn :-) Hab es gerade probiert. Es geht mir nicht um die Darstellung, sondern um den Wert für Depth.

Code:
COUNT(*)-1+(n.category_left>1) AS depth
hilft leider auch nicht
 
Was mir gerade so auffällt, wenn du aus deinem count ergbnis also die tiefe plus eins die wurzel ziehst und dann eins abziehst kommst du auf das richtige Ergebnis, also: SQRT(COUNT(p.category_id))-1
 
Hm ja tatsächlich, Danke.
Vielleicht finde ich auch irgendwann raus wieso :-D

Ergänzung:
Ein anderer Anseits der fast funktioniert ist:
Code:
SELECT n.*,
    count(*)-1+(n.category_left>1) AS depth
    FROM `blug_category` n,
         `blug_category` p
   WHERE n.category_left BETWEEN p.category_left AND p.category_right
     AND (p.category_id != n.category_id OR n.category_left = 1)
GROUP BY n.category_id
ORDER BY n.category_left
Hier habe ich das komische Problem, dass mit category_id = 3 fehlt (Automaten). Und zwar vollständig...?! Jemand eine Idee?
SQRT() ist leider nicht bei allen MySQL Servern erlaubt bzw. bekannt (sowie ROUND() ).
 
Zuletzt bearbeitet:
Also bei allen Beispielen im Internet sieht das ganze anders aus:

SELECT (COUNT(parent.id)-1) AS depth, node.id
FROM tree AS node, tree AS parent
WHERE node.l BETWEEN parent.l AND parent.r
GROUP BY node.id ORDER BY node.l;
 
Der letzte Ansatz entspricht von Arne Klempert und war eigentlich meine Insperation bzw. meine Hauptquelle wodurch ich erst überhaupt auf Nested Sets gestossen bin.
Der Umgang ist deutlich schwieriger, aber die Skalierbarkeit und Leistung spricht Bände ;)
 
Hast du es denn mal so probiert, wie ich es gepostet hab?

Aber man profitiert doch von Nested Stes nur, wenn man sie direkt ausgibt ansonsten erhält man doch keinen Perfomancegewinn.
 

Ähnliche Themen

Zurück
Oben