Opossom: prüfung in MySQL statement mit nodes

Einen wunderschönen gunten Morgen :)
Ich versuche mittels einem SQL Befehl posts mit 2 verschiedene Bedingungen aus einer db auszulesen. 1. damit der ganze Baum angezeigt wird, und 2. will ich eine zusätzliche Spalte wo blau oder gelb drinnen steht jeh nach dem ob der Post zum richtigen node gehört oder nicht.
Mein Code schaut zur Zeit so aus:

SELECT DISTINCT node.id, node.text,
case node.text when node.lft BETWEEN parent.lft AND parent.rgt AND node.id = 8 then "gelb" else "blau" end
FROM post AS node, post AS parent
WHERE node.lft
BETWEEN parent.lft
AND parent.rgt
AND parent.lft = '1'
ORDER BY node.lft

Leider setzt er überall blau hin außer beim Post mit der id 8 es sollte aber bei allen posts die damit über lft und rgt verkettet sind gelb stehen.
Wenn ich die case Bedingung jedoch in ein eigenes SELECT Statement einfüge und den rest um alle anderen Posts auch anzuzeigen weg lösche dann funktionierts... Ich weiß leider nicht mehr weiter. Ich hab schon versucht die case Bedingung nach dem FROM einzubauen damit er mit node und parent richtig umgeht das funktioniert leider nicht weil ich jedes Mal einen falschen Syntax bekomme.
Ich bin für jede Hilfe dankbar. MfG das Opossom

  1. Hi!

    case node.text when node.lft BETWEEN parent.lft AND parent.rgt AND node.id = 8 then "gelb" else "blau" end

    Du solltest dich nochmal mit dem CASE-Operator beschäftigen und der Bedeutung der Parameter. Zuerst wird der WHEN-Ausdruck ausgerechnet Aufgrund deiner drei mit AND verknüpften Teilausdrücke ergibt sich dabei ein boolscher Wert. Das Ergebnis des WHEN-Ausdrucks wird mit dem CASE-Ausdruck verglichen. Du vergleichst also einen Text mit einem boolschen Wert.

    Du könntest statt node.text TRUE oder FALSE einsetzen, damit boolean mit boolean verglichen wird. In deinem Fall halte ich jedoch die Verwendung der IF-Funktion für angebrachter und einfacher (in der Anwendung und in der Verständlichkeit des resultierenden Codes). CASE lohnt sich nur, wenn du mehrere WHEN-Ausdrücke gegen einen CASE-Asdruck vergleichen und unterschiedlich reagieren willst.

    Control Flow Functions

    Lo!

    1. Du könntest statt node.text TRUE oder FALSE einsetzen, damit boolean mit boolean verglichen wird. In deinem Fall halte ich jedoch die Verwendung der IF-Funktion für angebrachter und einfacher (in der Anwendung und in der Verständlichkeit des resultierenden Codes). CASE lohnt sich nur, wenn du mehrere WHEN-Ausdrücke gegen einen CASE-Asdruck vergleichen und unterschiedlich reagieren willst.

      Control Flow Functions

      Lo!

      Hi. Danke für die Antwort.
      Leider hab ichs mit der IF-Funktion schon versucht. Da bekomm ich genau so wie bei when, neben allen einträgen "blau" bis auf den mit der id die ich gesetzt hab, da steht dann gelb. Eigentlich sollte aber überall wo der Leaf Node die id 8 hat gelb stehen. Mein Code sieht jetzt so aus:

      SELECT DISTINCT node.id, node.text, IF (node.lft BETWEEN parent.lft AND parent.rgt AND node.id = 8, "gelb", "blau") AS groesse
      FROM post AS node, post AS parent
      WHERE node.lft
      BETWEEN parent.lft
      AND parent.rgt
      AND parent.lft = '1'
      ORDER BY node.lft

      Vlt. hab ich was falsch verstanden jedenfalls krieg ich das nicht so hin wie es sein soll.
      Danke MfG Opossom

      1. Hi!

        Leider hab ichs mit der IF-Funktion schon versucht. Da bekomm ich genau so wie bei when, neben allen einträgen "blau" bis auf den mit der id die ich gesetzt hab, da steht dann gelb. Eigentlich sollte aber überall wo der Leaf Node die id 8 hat gelb stehen. Mein Code sieht jetzt so aus:

        SELECT DISTINCT node.id, node.text, IF (node.lft BETWEEN parent.lft AND parent.rgt AND node.id = 8, "gelb", "blau") AS groesse

        Nur bei dem einen Datensatz ist ja auch die node.id = 8. Ich denke, dan der Stelle brauchst du feste Werte für lft und rgt von Node 8. Mit User-Defined Variables sieht das wie folgt aus. Wenn du die Werte bereits in einer früheren Abfrage ermittelt hast, dann nimm diese.

        SELECT @lft := lft, @rgt := rgt FROM node WHERE id = 8
          SELECT ... IF(node.lft < @lft AND node.rgt > @rgt, "gelb", "blau") ...

        Lo!

        1. SELECT @lft := lft, @rgt := rgt FROM node WHERE id = 8
            SELECT ... IF(node.lft < @lft AND node.rgt > @rgt, "gelb", "blau") ...

          Hi. Danke für deine Hilfe und sorry dass ich noch mal nerven muss.
          Der Code funktioniert ansich, nur aus irgend einem Grund funktionierts nur im phpmyadmin. Wenn ich ihn dann 1 zu 1 ins php file übernehme dann meckert er wegen der Syntax ab dem zweiten Select :(
          Muss ich beim php Code etwas beachten bzw. etwas anderst machen als in phpmyadmin? Eigentlich nicht oder? Der Script schaut derweil so aus:
          SELECT @lft := lft, @rgt := rgt FROM post AS color WHERE id = 8;
          SELECT DISTINCT node.id, node.text, IF(node.lft < @lft AND node.rgt > @rgt, "fontcolorgelb", "fontcolorblau") AS color
          FROM post AS node, post AS parent
          WHERE node.lft BETWEEN parent.lft AND parent.rgt AND parent.lft =  "1"
          Danke mfg Opossom

          1. Hi!

            Hi. Danke für deine Hilfe und sorry dass ich noch mal nerven muss.

            Kein Problem, nerven sieht ganz anders aus :-)

            Der Code funktioniert ansich, nur aus irgend einem Grund funktionierts nur im phpmyadmin. Wenn ich ihn dann 1 zu 1 ins php file übernehme dann meckert er wegen der Syntax ab dem zweiten Select :(

            Ja, das ist ein in der MySQL-API eingebauter Schutz gegen zu groben Unfug bei SQL-Injection-Lücken. Dass nur ein Statement pro mysql_query() ausgeführt werden kann, verhindert beispielsweise, dass Exploits of a Mom ohne weiteres erfolgreich funktioniert. phpMyAdmin weiß darum und teilt die Statemens am ; auf, um sie einzeln auszuführen. Wenn du hingegen mysqli als zu verwendende Extension angegeben hast, dann kann es mysqli_multiquery() nehmen. Das wären auch beide für dich gehbare Wege, wenn du die lft-rgt-Werte noch nicht aus einer früheren Abfrage kennst: zwei Statements oder mysqli_multiquery() verwenden, was eventuell ein Umsteigen auf mysqli nach sich zieht - was aber auch sonst keine schlechte Idee ist.

            Lo!

            1. Cool danke. So passts :)
              MfG Opossom