Nested Sets: alle Teilbäume, die bestimmte Elemente enthalten

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Nested Sets: alle Teilbäume, die bestimmte Elemente enthalten

    Hallo,

    wie man einen Baum aus einem Nested Set ermittelt, in dem ein bestimmtes Element vorhanden ist, weiß ich. Natürlich lässt sich das auch insofern erweitern, dass man für n gesuchte Elemente entsprechend n Bäume von Element e bis zur Wurzel ausgibt, was jedoch unsinnig viele Daten mehrfach erzeugt und die nachfolgende Verarbeitung kompliziert.

    Bevor ich zu meiner konkretisierten Farge komme, eine kurze Darstellung des gesamten Baumes:
    Code:
    Id: 1
     |
     |- Id: 2
        |- Id: 3
        |- Id: 4
        |- Id: 5
        |- Id: 6
        |- Id: 7
        |- Id: 8
     |- Id: 9
     |- Id: 10
        |- Id: 11
        |- Id: 12
        |- Id: 13
     |- Id: 14
     |- Id: 15
    Nehmen wir nun mal an, ich möchte diesen Baum haben, jedoch nicht mit allen Elementen, sondern nur mit den Elementen 4, 5 und 12, folglich:
    Code:
    Id: 1
     |
     |- Id: 2
        |- Id: 4
        |- Id: 5
     |- Id: 10
        |- Id: 12
    Wie ich diese Abfrage nun gestalten soll, entzieht sich bislang meiner Vorstellungskraft. Setze ich die gewünschten Elemente (4, 5, 12) in den Bedingungsteil der Abfrage, erhalte ich, je nach Formulierung, entweder

    NUR die gesuchten Elemente, nicht jedoch deren Eltern, sprich
    Code:
    SELECT
    	d2.*
    FROM
    	datatest d1,
    	datatest d2
    WHERE
    	d1.lft BETWEEN d2.lft AND d2.rgt
    AND
    	d2.id IN (4, 5, 12
    AND
    	d2.root_id = 1
    AND
    	d2.active = 1
    AND
    	d1.active = 1
    GROUP BY
    	d2.id
    ORDER BY
    	d1.lft, d2.lft
    
    |- Id: 4
    |- Id: 5
    |- Id: 12
    oder je einen gesamten Baum für jedes gesuchte Element, sprich
    Code:
    SELECT
    	d2.*
    FROM
    	datatest d1,
    	datatest d2
    WHERE 
    	d1.lft BETWEEN d2.lft AND d2.rgt
    AND 
    	d1.id IN (4, 5, 12)
    AND
    	d2.root_id = 1
    AND
    	d2.active = 1
    AND
    	d1.active = 1
    ORDER BY 
    	d1.lft, d2.lft
    
    Id: 1
     |
     |- Id: 2
        |- Id: 4
    Id: 1
     |
     |- Id: 2
        |- Id: 5
    Id: 1
     |
     |- Id: 10
        |- Id: 12
    Gibt es hier eine (vielleicht sogar verständliche) Lösung? Die Datenbanktabelle mit Testdaten habe ich als SQL-Datei diesem Posting angehängt. Sie ist so ausgelegt, dass man am besten mit den "gewünschten Elementen" 110, 111 und 136 arbeiten kann.

    Vielen Dank schon im Voraus.

    pb
    Angehängte Dateien

  • #2
    Hallo Leute!

    da ich aktuell vor genau dem gleichen Problem stehe, möchte ich diesen Thread nochmal reaktivieren.. Vielleicht weiß ja inzwischen jemand ne Lösung.. =)

    MfG

    Kommentar


    • #3
      Hallo,

      mir ist keine Abfragemöglichkeit bekannt, die genau das mit nur einem Statement und für beliebige Tiefen bewerkstelligen könnte. Mit multiplen Self Joins (z. B. Anzahl n) kann man aber maximal n Elternelemente mit anzeigen, was gewissermaßen schon mal in die Richtung geht.

      Mit einer gespeicherten Prozedur und einer temporären Tabelle sollte es allerdings gut machbar sein.

      Edit: Wenn es in Frage käme, die Abfrage auf Basis der gesuchten Werte mit PHP entsprechend zusammenzubauen, gibt es noch eine weitere Lösung: Für jeden Knoten dessen Stammbaum abzufragen ist ja kein Problem. Für mehrere solcher Stammbäume bietet sich dann Union an.

      Gruß,

      Amica
      Zuletzt geändert von AmicaNoctis; 28.06.2010, 19:13.
      [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
      Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
      Super, danke!
      [/COLOR]

      Kommentar


      • #4
        Momeeent, wenn ich das jetzt richtig verstanden habe, wäre das ja genau was ich suche...

        Also, ich würde quasi den SQL Befehl mit php zusammensetzen und jeweils jedes Element mit all seinen Übergeordneten Knoten abfragen und das dann verknüpfen mit union (select blablabla1 union select blablabla2 usw)

        Und dann werden mir alle doppelt vorhandenen knoten quasi rausgeschmissen?
        das wär ja genial!! =)

        vielen dank schonmal! ich hab grad leider keine Zeit das zu testen, aber grundsätzlich richtig verstanden hab ich das jetzt doch, oder?

        Gruß und schönen Abend noch,
        Simon

        Kommentar


        • #5
          Was meinst du damit, dass doppelte rausfallen? Ich dachte, du willst zu jedem gesuchten Knoten den kompletten Stammbaum dazu, also z. B. wenn man 20, 24 und 14 sucht:

          1 – 5 – 11 – 20
          1 – 5 – 11 – 21 – 24
          1 – 5 – 14

          und nicht nur
          1, 5, 11, 20, 21, 24, 14

          Wenn du letzteres suchst und den jeweiligen Stammbaum dann mit PHP wieder zuordnen willst, kannst du auch gleich mit OR arbeiten:

          Code:
          where (lft <= :al and rgt >= :ar)
             or (lft <= :bl and rgt >= :br)
             or (lft <= :cl and rgt >= :cr)
          [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
          Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
          Super, danke!
          [/COLOR]

          Kommentar


          • #6
            also eigentlich möchte ich am ende ein mehrdimensionales array haben, dass quasi den teil des gesamten stammbaumes enthällt, der zu den gesuchten elementen führt:

            Code:
            array 1 (
                         array 5 (
                                     array 11 (
                                                  20
                                                  array 21 (
                                                               24)
                                                  )
                                    14
                                   )
                       )

            Kommentar


            • #7
              Da du aus MySQL nie so ein Array zurückbekommen wirst , musst du sowieso einen Gruppenwechsel in PHP durchführen. Es wäre also wirklich besser, gleich mit OR ranzugehen.
              [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
              Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
              Super, danke!
              [/COLOR]

              Kommentar


              • #8
                hmm, ok..

                was genau meinst du mit gruppenwechsel? sagt mir jetzt irgendwie nichts der begriff... =(

                wie komm ich denn dann mit mysql und dann mit php zu so einem array.. sry, aber steh grad irgendwie ein bisschen auf der leitung..

                vielen dank für deine freundliche hilfsbereitschaft!

                Kommentar


                • #9
                  Zitat von Simon1990 Beitrag anzeigen
                  was genau meinst du mit gruppenwechsel? sagt mir jetzt irgendwie nichts der begriff... =(
                  Dann suche bitte danach!
                  I don't believe in rebirth. Actually, I never did in my whole lives.

                  Kommentar


                  • #10
                    Zitat von Simon1990 Beitrag anzeigen
                    was genau meinst du mit gruppenwechsel?
                    Ich weiß nicht, ob es dir hilft und es ist auch nicht brillant geschrieben, aber ich hab dazu was in meinem Blog.
                    [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
                    Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
                    Super, danke!
                    [/COLOR]

                    Kommentar

                    Lädt...
                    X