Tabellenverknüpfungen :/



  • MySql-Doofi schrieb:

    Ergebnis sind auch wieder alle Kinder der Wurzel.
    Allerdings braucht man jetzt hier, und so weit ich das erkennen kann, bei deiner Variante auch, immer zwei Parameter, um die Ergebnisse darstellen zu können. Das Level und die ID des entsprechenden Astes bei dieser Variante, das Level und die lft/rgt-Werte des entsprechenden Astes bei deiner Variante.

    Ja, das sehe ich auch so, ich denke da kommt man auch nicht drumherum. 😞

    MySql-Doofi schrieb:

    Die HAVING-Klausel sieht wirklich sehr vielversprechend aus!
    Was für Werte stehen bei dir in tr_root, ich habe diese Spalte nicht.

    Ich hab' bei meiner Beispiel-Tabelle die Möglichkeit mehrere Bäume in dieser Tabelle zu speichern, also mehrere Wurzeln. In tr_root steht also immer die tr_id der Wurzel. Wenn es sich um die Wurzel selbst handelt, dann ist tr_id = tr_root. Habe ich bei irgendeiner Seite so gesehen und gefiel mir. 🙂



  • oO

    Du machst mir das zu kompilziert. 😉
    Ich glaube ein mühevolles anpassen deines Query kann ihc mir sparen, läuft ja eh auf das selbe raus.

    Nochmal zu den Leveln, das Level des Kindes eines Astes ist um 1 größer als das Level des Elternastes.

    Wenn man jetzt die ID des Elternastes hat und somit das Level ermitteln kann, möchte man doch meinen, dass das ausreicht, um alle Kinder darzustellen. Aber ich krieg es auch nicht hin... 😞



  • Jetzt bin ich verwirrt. 🙂

    Also, meiner Meinung nach brauchst Du die lft-/rgt-Werte und das level, um die Kinder darzustellen, was imho auch logisch ist. Nehmen wir mal folgenden Baum:

    A
    |- B
    |  |- C
    |  `- D
    `- E
       |- F
       `- G
    

    Dazu gehört folgende Tabelle:

    +-------+---------+---------+--------+--------+-------+
    | tr_id | tr_root | tr_name | tr_lft | tr_rgt | level |
    +-------+---------+---------+--------+--------+-------+
    |     1 |       1 | A       |      1 |     14 |     0 |
    |     2 |       1 | B       |      2 |      7 |     1 |
    |     3 |       1 | C       |      3 |      4 |     2 |
    |     4 |       1 | D       |      5 |      6 |     2 |
    |     5 |       1 | E       |      8 |     13 |     1 |
    |     6 |       1 | F       |      9 |     10 |     2 |
    |     7 |       1 | G       |     11 |     12 |     2 |
    +-------+---------+---------+--------+--------+-------+
    

    Wenn ich jetzt alle Kinder von 'B' haben möchte, dann muss ich doch alle Datensätze holen, die level 2 = getLevel('B')+1 und tr_lft > 2 und tr_rgt < 7 haben. Wenn ich die Bedingung der lft-/rgt-Werte weglasse, dann bekomme ich ja zusätzlich 'F' und 'G' als Kinder ausgegeben, was ja falsch wäre.

    Hab' Dein Statement mit der ID (ohne lft/rgt) nicht überprüft, daher weiß ich nicht genau, ob das so läuft, daher hier nur die Erklärung, warum das mit den lft/rgt-Werte laufen sollte.

    Die lft/rgt-Werte in einem Teilbaum TB eines Knotens K liegen immer zwischen den lft/rgt-Werten von K, deswegen ist dies als Filter-Bedingung imho unerlässlich.



  • Nochmal am Beispiel, alle Kinder von A anzeigen zu lassen:

    +-------+---------+---------+--------+--------+-------+
    | tr_id | tr_root | tr_name | tr_lft | tr_rgt | level |
    +-------+---------+---------+--------+--------+-------+
    |     1 |       1 | A       |      [b]1[/b] |     [b]14[/b] |     0 |
    |     2 |       1 | B       |      [b]2[/b] |      [b]7[/b] |     1 |
    |     3 |       1 | C       |      3 |      4 |     2 |
    |     4 |       1 | D       |      5 |      6 |     2 |
    |     5 |       1 | E       |      [b]8[/b] |     [b]13[/b] |     1 |
    |     6 |       1 | F       |      9 |     10 |     2 |
    |     7 |       1 | G       |     11 |     12 |     2 |
    +-------+---------+---------+--------+--------+-------+
    

    Gegeben ist nur der lft-Wert von A!
    1 -> 2 -> 7 -> 8 -> 13 -> 14
    Alle Äste verhalten sich da ähnlich wie in einem Parent-Baum.
    Für alle Äste, außer der Wurzel gilt immer:
    row1.tr_rgt = row2.tr_lft+1

    Warum kann man das nicht nutzen? Ich probiere immer noch damit rum...



  • Um das zu machen müsstest Du ein Statement bauen, welches so ähnlich aussieht:

    select * from `tree` 
    where `tr_lft` = 2 or (`tr_lft` > 2 and `tr_lft` = `prev_row`.`tr_rgt` + 1)
    order by `tr_lft` asc
    

    wobei Du hier natürlich einen Ausdruck für `prev_row` bräuchtest, den es afaik nicht gibt.

    Mag sein, dass ich mich irre, aber ich glaube, dass man auf Felder des vorherigen Datensatzes in einer Liste nicht zugreifen kann.

    Evtl. würde eine Möglichkeit bestehen, wenn Du die gleiche Liste, also in diesem Beispiel B und C versetzt aneinander joinen würdest, Du also eine Liste der Form

    +---------+--------+--------+----------+---------+---------+
    | tr_name | tr_lft | tr_rgt | tr_name2 | tr_lft2 | tr_rgt2 |
    +---------+--------+--------+----------+---------+---------+
    | B       |      2 |      7 | A        |       1 |      14 |
    | E       |      8 |     13 | B        |       2 |       7 |
    +---------+--------+--------+----------+---------+---------+
    

    Wenn Du einen Join in der Form hinbekommst, dann kannst Du ja einfach ein

    where tr_lft = tr_lft2 + 1 or tr_lft = tr_rgt2 + 1
    

    dranhängen, dann müsste das laufen.

    Nur, wenn Du soweit bist, dass Du genau diese Liste dranjoinen kannst, dann brauchst Du eigentlich nicht mehr weitermachen, weil Du ja dann schon die Liste gefunden hast, die Dich interessiert.

    Also, ich denke, das klappt so nicht, wie Du Dir das vorstellst. 😞

    Oder hast Du evtl. in der Zwischenzeit eine Lösung gefunden? 😃



  • Ne, hab die Idee jetzt verworfen, und wie du weiter oben schon vorgeschlagen hast, eine zusätzliche Spalte level eingefügt. Funktioniert prima und ich bin soweit auch zufrieden. 🙂

    mantiz, vielen vielen Dank für deine Hilfe, hast mir wirklich sehr gut geholfen! 👍


Anmelden zum Antworten