Warnung: file_put_contents(/home/www/web1/html/php_dev/test.txt) [function.file-put-contents]: failed to open stream: Permission denied in /home/www/web1/html/php_dev/sys/lib.activity.php (Zeile 58)
Nested Set: Bestimmten Level abfragen [Archiv] - PHP-Scripte PHP-Tutorials PHP-Jobs und vieles mehr

- Ad -
php-resource




Archiv verlassen und diese Seite im Standarddesign anzeigen :
Nested Set: Bestimmten Level abfragen


 
PHPler
12-11-2007, 13:41 
 
Hallo!

Ich habe ein Nested Sets System, z.B.

Name | LFT | RGT | LEVEL
Root | 1 | 8 | 1
Child | 2 | 5 | 2
Subchild | 3 | 4 | 3
Child 2 | 6 | 7 | 2

Nun möchte ich alle Einträge aus der Datenbank holen, die auf Ebene X liegen, also wenn ich z.B. Ebene 2 angebe, soll mir die Abfrage Child und Child 2 zurückliefern.

Wie stell ich das an? Frickel schon die ganze Zeit an einer Abfrage rum, komm aber kein Stück weiter. Danke!

 
Berni
12-11-2007, 14:25 
 
"select * from bla where LEVEL = 2"

 
hhcm
12-11-2007, 14:32 
 
:rofl:

 
PHPler
12-11-2007, 14:57 
 
*lol* sorry, ihr habt mich falsch Verstanden!

Level steht da nur als Beispiel. Es ist KEIN Element der Tabelle (hätte ich villeicht dazuschreiben sollen). Mit der folgenden Abfrage

SELECT db1.name AS name, COUNT(*) AS level FROM tabelle AS db1, TABELLE AS db2 WHERE db1.lft BETWEEN db2.lft AND db2.rgt GROUP BY db1.lft ORDER BY db1.lft, db1.rgt

Wird automatisch der Level zu jedem Eintrag berechnet. Nun möchte ich aber nur die Einträge haben, denen Level x entspricht. Nur funzt das weder wenn ich in die WHERE klausel z.B. WHERE level = 2 noch WHERE COUNT(*) = 2 oder sonstiges reinhau.

Also wie muß da die Abfrage umgestrickt werden?

 
onemorenerd
12-11-2007, 15:10 
 
Mit ALTER TABLE eine Spalte "Level" hinzufügen und dein SELECT von oben zu einem UPDATE umbauen. Dann löst Bernis Query dein Problem.

 
PHPler
12-11-2007, 15:13 
 
Hm, stimmt auch. Werd ich gleich mal probieren. Danke! :)

 
unset
12-11-2007, 15:26 
 
In einer größeren Anwendung löse ich das Problem über eine zusätzliche Spalte, in der ich den Pfad noch einmal vorhalte. So kann man auch schnell von unten nach oben auflösen:


Name | ID | LFT | RGT | PATH
Root | 0 | 1 | 8 |
Child | 1 | 2 | 5 | 0
Subchild | 2 | 3 | 4 | 0-1
Child 2 | 3 | 6 | 7 | 0

 
zaubatrik
12-11-2007, 16:08 
 
Um das Problem zu lösen must Du nur noch ein "HAVING level = 2" an deine bereits vorhandene Query anhängen.

SELECT db1.name AS name, COUNT(*) AS level FROM tabelle AS
db1, TABELLE AS db2 WHERE db1.lft BETWEEN db2.lft AND db2.rgt
GROUP BY db1.lft HAVING level = 2 ORDER BY db1.lft, db1.rgt

Dadurch brauchst Du auch keine extra Spalte in deiner Tabelle und das "geniale" an Nested-Sets - welche Du ja verwendest - wird sichtbar.

Schöne Grüße

zaubatrik

 
onemorenerd
12-11-2007, 16:12 
 
Die zusätzliche Spalte würde genau das selbe leisten wie ein HAVING. Aber man würde nicht bei jeder Anfrage eine Query mit JOIN, BETWEEN, GROUP BY und ORDER ausführen, sondern nur bei INSERTS und UPDATES.

Wenn also oft nach Einträgen mit bestimmtem Level gefragt wird, würde ich mir den Luxus einer zusätzlichen int-Spalte gönnen.
Wenn andererseits oft Daten verändert werden, würde ich wiederum HAVING bevorzugen.

 
PHPler
12-11-2007, 17:03 
 
Ach siehste! Das mit dem HEAVING wusst ich nicht. Denke aber in dem Fall macht es auch mehr sinn die Abfrage mit einer extra Tabelle zu machen, auch wenn ich jedesmal die Levels neu updaten müsste beim hinzufügen, verschieben oder entfernen von Einträgen. Aber gut zu wissen für den fall, falls ich das HEAVING mal anderweitig brauchen sollte. Danke! :)

 
zaubatrik
12-11-2007, 18:50 
 
Nested-Sets zeichen sich doch aber gerade dadurch aus das ich mit ener Query ganze Bäume abbilden kann. Aber wie dem auch sei, es führen viele Wege nach Rom.


Alle Zeitangaben in WEZ +2. Es ist jetzt 23:09 Uhr.