Malcolm Beck´s: IF in einem SELECT-Statement

hi,

gibt es so eine art IF für SELECT-Statements, so was wie Bspw:

  
SELECT  
        feld_1, feld_2,  
        optionales_feld  
FROM  
        table  
WHERE  
        feld_1 = 'wert'  
AND  
        IF (optionales_feld) -- Wenn vorhanden  
        {  
          optionales_feld = 'wert'  
        }  

Wenn ich das Statement ohne IF schreiben würde, bekomme ich kein Resultat, wenn "optionales_feld_1" keinen Wert hat.
Dadurch könnte ich mir ein zusätzliches SELECT einsparen, mit dem ich vorher prüfen muss, ob in "optionales_feld_1" was steht.

Hab schon ein wenig Recherchiert aber nichts passendes gefunden, bzw. fehlen mir ein Paar Schlagworte, nach denen ich suchen kann.

mfg

--
echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
array(2) {
  ["SELFCODE"]=>
  string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
  ["Meaningful"]=>
  string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
}
  1. Hi Malcolm!

    Wenn ich das Statement ohne IF schreiben würde, bekomme ich kein Resultat, wenn "optionales_feld_1" keinen Wert hat.

    Wieso verknüpfst du nicht einfach disjunktiv (OR) eine Abfrage, ob das Feld leer ist?

    MfG H☼psel

    --
    "It's amazing I won. I was running against peace, prosperity, and incumbency."
    George W. Bush speaking to Swedish Prime Minister unaware a live television camera was still rolling, June 14, 2001
    Selfcode: ie:% fl:( br:> va:) ls:& fo:) rl:? n4:& ss:| de:] js:| ch:? sh:( mo:) zu:)
    1. hi Hopsel,

      » Wenn ich das Statement ohne IF schreiben würde, bekomme ich kein Resultat, wenn "optionales_feld_1" keinen Wert hat.
      Wieso verknüpfst du nicht einfach disjunktiv (OR) eine Abfrage, ob das Feld leer ist?

      OR greift doch nur, wenn WHERE nicht passt, oder habe ich OR falsch verstanden? Ich hatte es schon mit OR versucht, ohne Erfolg.

      mfg

      --
      echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
      array(2) {
        ["SELFCODE"]=>
        string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
        ["Meaningful"]=>
        string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
      }
      1. Hi,

        Wieso verknüpfst du nicht einfach disjunktiv (OR) eine Abfrage, ob das Feld leer ist?

        OR greift doch nur, wenn WHERE nicht passt, oder habe ich OR falsch verstanden?

        OR verknüpft mehrere Einzelbedingungen per logischem Oder.
        Die resultierende Gesamtbedingung hinter WHERE muss erfüllt sein, damit der Datensatz selektiert wird.

        MfG ChrisB

        --
        Light travels faster than sound - that's why most people appear bright until you hear them speak.
      2. Hi Malcolm!

        OR greift doch nur, wenn WHERE nicht passt, oder habe ich OR falsch verstanden? Ich hatte es schon mit OR versucht, ohne Erfolg.

        Ohne mir die anderen Antworten durchzulesen:
        Deine Tabellen sind doch nach folgendem Schema aufgebaut:

        Tabelle_1

        feld_1  feld_2  optional
        4       56      43
        13      23      NULL
        13      2       23
        13      34      6

        Du möchtest jetzt alle Datensätze, die bei feld_1 den Wert 13 und bei dem optionalen Feld entweder NULL oder 23 haben.

        SELECT feld_1,feld_2  
        FROM Tabelle_1  
        WHERE feld_1 = 13  
          AND ( optional IS NULL  
             OR optional = 23 )
        

        Richtig?

        MfG H☼psel

        --
        "It's amazing I won. I was running against peace, prosperity, and incumbency."
        George W. Bush speaking to Swedish Prime Minister unaware a live television camera was still rolling, June 14, 2001
        Selfcode: ie:% fl:( br:> va:) ls:& fo:) rl:? n4:& ss:| de:] js:| ch:? sh:( mo:) zu:)
        1. hi Hopsel,

          Deine Tabellen sind doch nach folgendem Schema aufgebaut:

          Tabelle_1

          feld_1  feld_2  optional
          4       56      43
          13      23      NULL
          13      2       23
          13      34      6

          Danke für das Beispiel, aber ich habe dank ChrisB das Problem mittlerweile einfacher lösen können.

          Mein Problem war, dass ich nicht wusste, wie man mit Daten aus der DB ein Mehrdimensionales Array bildet.

          mfg

          --
          echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
          array(2) {
            ["SELFCODE"]=>
            string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
            ["Meaningful"]=>
            string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
          }
        2. hi H☼psel,

          SELECT feld_1,feld_2

          FROM Tabelle_1
          WHERE feld_1 = 13
            AND ( optional IS NULL
               OR optional = 23 )

          
          >   
          > Richtig?  
            
          Ich habe jetzt noch einen Fall in meiner DB gefunden, wo eine IF Sinnvoll wäre, mit deinem Beispiel hat es schon mal nicht geklappt.  
            
          Gegeben sind die Tabellen:  
            
          ~~~sql
          -- Daten für Tabelle cms_content  
            
          id | content | group_id | user_comments  
          ---------------------------------------  
          1  | Texte   | 12       | 1  -- erlaubt  
          2  | texte2  | 15       | 0  -- nicht erlaubt  
          3  | Texte3  | 22       | 1  -- erlaubt  
            
            
          -- Daten für Tabelle cms_comments  
            
          id | comments | group_id  
          ------------------------  
          1  | comment1 | 12  
          2  | comment2 | 12  
          3  | comment3 | 22  
          
          
            
          SELECT  
                 content, user_comments  
                 , comments  
          FROM  
                 cms_content, cms_comments  
          WHERE  
                 cms_content.group_id = 12  
          AND  
                 cms_comments.group_id = 12  
          
          

          Das liefert mir die richtigen Daten, allerdings nur, wenn es auch Kommentare mit entsprechender ID gibt, ansonsten bekomme ich keine Datensätze.

          Das heisst, über das SELECT muss erst einmal festgestellt werden, ob Kommentare überhaupt erlaubt sind (user_comments = 1), und wenn ja, ob es zu der gegebenen „group_id“ auch welche gibt.

          Also etwas in der art wie (Pseudocode):

            
          SELECT  
                 content, user_comments  
          FROM  
                 cms_content  
          WHERE  
                 cms_content.group_id = 12  
            
          IF (user_comments == 1)  
          {  
            SELECT  
                    comments  
            FROM  
                    cms_comments  
            WHERE  
                    cms_comments.group_id = 12  
          }
          

          Ist sowas in dieser richtung überhaupt möglich oder muss ich das über 2 SELECT lösen?

          mfg

          --
          echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
          array(2) {
            ["SELFCODE"]=>
            string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
            ["Meaningful"]=>
            string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
          }
          1. Ist sowas in dieser richtung überhaupt möglich oder muss ich das über 2 SELECT lösen?

            Ich versteh nicht warum du das nicht einfach in die WHERE Bedingung einbaust. IF hat bei einer SQL Abfrage eine völlige andere Bedeutung, es steuert keine Ablauf, sondern lediglich das Ergebniss und dort nur die Felder. alles andere kommt in die where klausel.

            Natürlich könntest du in deinem Beispiel auch einen subselect bauen, aber warum?

            WHERE  
                   ( cms_content.group_id = 12  
            AND  
                   cms_comments.group_id = 12) AND  
            cms_comments.user_comments = 1  
            
            

            sollte doch funktionieren, oder nicht?

            Wobei das ganze eigentlich ja ein Fall für einen join ist.

            Struppi.

          2. Hi Malcolm!

            Ist sowas in dieser richtung überhaupt möglich [...]

            ´türlich!

            SELECT  
                   content, user_comments  
                   , comments  
            FROM  
                   cms_content  
            LEFT JOIN cms_comments  
            ON     cms_comments.group_id = 12  
            WHERE  cms_content.group_id = 12
            

            Bei einem Left Outer Join werden fehlende Treffer der rechten Tabelle mit NULL aufgefüllt.

            MfG H☼psel

            --
            "It's amazing I won. I was running against peace, prosperity, and incumbency."
            George W. Bush speaking to Swedish Prime Minister unaware a live television camera was still rolling, June 14, 2001
            Selfcode: ie:% fl:( br:> va:) ls:& fo:) rl:? n4:& ss:| de:] js:| ch:? sh:( mo:) zu:)
            1. hi,

              SELECT

              content, user_comments
                     , comments
              FROM
                     cms_content
              LEFT JOIN cms_comments
              ON     cms_comments.group_id = 12
              WHERE  cms_content.group_id = 12

              
              >   
              > Bei einem Left Outer Join werden fehlende Treffer der rechten Tabelle mit `NULL`{:.language-sql} aufgefüllt.  
                
              Danke für das Beispiel, sowas habe ich gesucht. Ich muss unbedingt diese JOIN-Geschichte verstehen, die ist sehr nützlich.  
                
              Jetzt kann ich die Kommentare direkt beim Aufruf der Seite zählen, statt mit einem zusätzlichem SELECT.  
                
              Eine Frage hätte ich noch zu dem obigen Beispiel; besteht die möglichkeit, dass ich die ON-Klausel nach einem WHERE einbaue?  
              Bei einem kurzen Test hat es nicht geklappt.  
                
              Also sowas wie:  
                
              ~~~sql
              FROM  
                     cms_content  
              LEFT JOIN cms_comments  
              WHERE  
                     cms_key.id = '$_GroupKey'  
              ON  
                     cms_comments.group_id = cms_key.id  
              AND  
                     cms_content.group_id = cms_key.id
              

              mfg

              --
              echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
              array(2) {
                ["SELFCODE"]=>
                string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
                ["Meaningful"]=>
                string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
              }
              1. Danke für das Beispiel, sowas habe ich gesucht. Ich muss unbedingt diese JOIN-Geschichte verstehen, die ist sehr nützlich.

                Jetzt kann ich die Kommentare direkt beim Aufruf der Seite zählen, statt mit einem zusätzlichem SELECT.

                Eine Frage hätte ich noch zu dem obigen Beispiel; besteht die möglichkeit, dass ich die ON-Klausel nach einem WHERE einbaue?

                Waeum?
                Die ON Klausel gehört zum join

                Struppi.

                1. hi,

                  » Eine Frage hätte ich noch zu dem obigen Beispiel; besteht die möglichkeit, dass ich die ON-Klausel nach einem WHERE einbaue?

                  »

                  Waeum?

                  Mit dem derzeitigen Model muss ich zuerst einmal die benötigte ID ermitteln, mit der ich arbeiten kann, also 2 SELECTs absetzen, nun dachte ich mir, dass man das vielleicht mit einem SELECT erledigen könnte.

                  Aktueller stand:

                  -- mit dem ersten SELECT ermittel ich die ID der aufgerufenen Seite  
                    
                  SELECT  
                         id  
                  FROM  
                         content_linking  -- über content_linking.id verknüpfe ich alle benötigten Tabellen miteinander  
                  WHERE  
                         content_linking.link_search_target = '" . $escape($SERVER['REQUEST_URI']) . "'  
                    
                    
                  -- Mit dieser ID kann ich dann weiter arbeiten  
                  -- (verkürzte Version, Normalerweise spreche ich mit diesem SELECT mehr Felder an)  
                    
                  SELECT  
                         content, count(comments)  
                  FROM  
                         content_linking, content  
                  LEFT JOIN  
                         user_comments_db  
                  ON  
                         user_comments_db.group_id = '" . $escape($SiteID) . "'  -- $SiteID muss ich vorher mit einem zusätzlichen SELECT ermitteln  
                  WHERE  
                         content_linking.id = '" . $escape($SiteID) . "'  
                  AND  
                         content.group_id = content_linking.id  
                  GROUP BY  
                         content.group_id
                  

                  Ich weiss, das ich im 2ten SELECT auf die erste WHERE-Klausel verzichten könnte, da ich die ID bereits habe, ich habe sie nur eingefügt, um mein Problem besser schildern zu können.

                  Mein versuch, diese 2 SELECT zu verbinden:

                  SELECT  
                         content, count(comments)  
                  FROM  
                         content_linking, content  
                  LEFT JOIN  
                         user_comments_db  
                  ON  
                         user_comments_db.group_id = content_linking.id  -- Das funktioniert nicht, da ich content_linking.id erst nach der WHERE-Klausel kenne  
                  WHERE  
                         content_linking.link_search_target = '" . $escape($SERVER['REQUEST_URI']) . "'  
                  AND  
                         content.group_id = content_linking.id  
                  GROUP BY  
                         content.group_id
                  

                  Hoffentlich ist es Verständlich, ich weiss nämlich nicht, wie ich das Problem genauer schildern kann.

                  mfg

                  --
                  echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
                  array(2) {
                    ["SELFCODE"]=>
                    string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
                    ["Meaningful"]=>
                    string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
                  }
                  1. Hoffentlich ist es Verständlich, ich weiss nämlich nicht, wie ich das Problem genauer schildern kann.

                    Du solltest dir noch mal anschauen was joins machen. Im join wird nichts ermittelt, sondern, wie der Name schon sagt, verknüpft. D.h. du verknüpfst zwei Tabellen über ein Feld und in der Where Klausel filterst du die aus die du haben willst. Du kannst dort also ganz normal, wie bei jedem anderen select, die Bedingung angeben die du möchtest.

                    Struppi.

                  2. Mahlzeit Malcolm Beck´s,

                    Mit dem derzeitigen Model muss ich zuerst einmal die benötigte ID ermitteln, mit der ich arbeiten kann, also 2 SELECTs absetzen, nun dachte ich mir, dass man das vielleicht mit einem SELECT erledigen könnte.

                    Aber sicher sollte das gehen.

                    -- mit dem ersten SELECT ermittel ich die ID der aufgerufenen Seite

                    SELECT
                           id
                    FROM
                           content_linking  -- über content_linking.id verknüpfe ich alle benötigten Tabellen miteinander
                    WHERE
                           content_linking.link_search_target = '" . $escape($SERVER['REQUEST_URI']) . "'

                    Einerseits möchte ich Dich auf [link:http://community.de.selfhtml.org/zitatesammlung/zitat1353@title=Zitat 1353] verweisen (woher sollen Deine Leser wissen, was in welcher Variable steht?) ...

                    -- Mit dieser ID kann ich dann weiter arbeiten
                    -- (verkürzte Version, Normalerweise spreche ich mit diesem SELECT mehr Felder an)

                    SELECT
                           content, count(comments)
                    FROM
                           content_linking, content
                    LEFT JOIN
                           user_comments_db
                    ON
                           user_comments_db.group_id = '" . $escape($SiteID) . "'  -- $SiteID muss ich vorher mit einem zusätzlichen SELECT ermitteln
                    WHERE
                           content_linking.id = '" . $escape($SiteID) . "'
                    AND
                           content.group_id = content_linking.id
                    GROUP BY
                           content.group_id

                      
                    ... zum anderen ist diese Query unsauber: Du vermischt implizite und explizite JOIN-Syntax. Allein schon aus Gründen der Übersichtlichkeit solltest Du das nicht tun - ganz davon abgesehen, dass dadurch evtl. unerwartete Ergebnisse zustandekommen. Dir Frage ist: was willst Du?  
                      
                    Ich versuche mal, Deine Versuche zu "begradigen":  
                      
                    ~~~sql
                    SELECT content                                         -- Gib mir den Inhalt  
                    ,      count(comments) AS anzahl_comments              -- und die Anzahl der Kommentare  
                      FROM content_linking       cl                        -- aller Datensätze aus der Tabelle "content_linking"  
                      LEFT JOIN content          c  ON cl.id = c.group_id  -- verknüpft mit der Tabelle "content"  
                      LEFT JOIN user_comments_db uc ON cl.id = uc.group_id -- verknüpft mit der Tabelle "user_comments_db"  
                     WHERE cl.link_search_target = 'foobar'                -- bei denen das Feld "link_search_target" den gewünschten Inhalt hat  
                     GROUP BY content                                      -- und gruppiere nach dem Inhalt
                    

                    Du solltest nur Felder selektieren, nach denen Du auch gruppierst. Umgekehrt solltest Du nach allen Feldern gruppieren, bei deren Selektion Du keine Aggregatsfunktion benutzt. MySQL ist da zwar tolerant, kann aber auch unerwartete Ergebnisse bringen: wenn Du die Datensätze nach der "content.group_id" gruppierst, woher soll das DBMS wissen, welchen der ggf. mehrfach vorkommenden "content" Du als Ergebnis haben möchtest?

                    SELECT

                    content, count(comments)
                    FROM
                           content_linking, content
                    LEFT JOIN
                           user_comments_db
                    ON
                           user_comments_db.group_id = content_linking.id  -- Das funktioniert nicht, da ich content_linking.id erst nach der WHERE-Klausel kenne

                    Nein - das funktioniert deshalb nicht, weil offenbar explizite JOIN-Syntax vor impliziter behandelt wird. Dein DBMS verknüpft anscheinend erst die Tabelle "content" mit der Tabelle "user_comments_db" ... und dabei sind natürlich Spalten aus der Tabelle "content_linking" noch nicht bekannt. Das ist das, was ich weiter oben meinte: sorge dafür, dass Deine SQL-Syntax sauber ist und vermeide die Vermischung von expliziter und impliziter JOIN-Syntax!

                    WHERE
                           content_linking.link_search_target = '" . $escape($SERVER['REQUEST_URI']) . "'
                    AND
                           content.group_id = content_linking.id
                    GROUP BY
                           content.group_id

                      
                      
                    MfG,  
                    EKKi  
                    
                    -- 
                    sh:( fo:| ch:? rl:( br:> n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
                    
                    1. hi EKKi,

                      Sorry für die verspätete Rückmeldung, war die Tage ein wenig beschäftigt.

                      » ~~~sql

                      content_linking.link_search_target = '" . $escape($SERVER['REQUEST_URI']) . "'

                      Einerseits möchte ich Dich auf [link:http://community.de.selfhtml.org/zitatesammlung/zitat1353@title=Zitat 1353] verweisen (woher sollen Deine Leser wissen, was in welcher Variable steht?) ...

                      Ich wusste nicht, was ich da hinschreiben sollte; [code lang=php]$SERVER['REQUEST_URI']

                        
                      
                      > ... zum anderen ist diese Query unsauber: Du vermischt implizite und explizite JOIN-Syntax. Allein schon aus Gründen der Übersichtlichkeit solltest Du das nicht tun - ganz davon abgesehen, dass dadurch evtl. unerwartete Ergebnisse zustandekommen. Dir Frage ist: was willst Du?  
                        
                      Exakt das, was dein Beispiel liefert, Danke für die begradigung!  
                      Ich habe mich zwar schon in die „Einführung in Joins“ reingelesen, aber dass wird wohl noch ne weile dauern, bis ich verstehe, wie dass ganze funktioniert.  
                        
                      
                      > Vermischung von expliziter und impliziter JOIN-Syntax!  
                        
                      Nur eine Verständnisfrage:  
                        
                      „Implizit“ ist eine direkte WHERE-Klausel ohne JOIN  
                      und  
                      „Explizit“ dann mit JOIN?  
                        
                      Danke jedenfalls für die Hilfe, jetzt kann ich mir 2 (vielleicht auch mehr SELECTs) einsparen.  
                        
                      mfg
                      
                      -- 
                      echo '<pre>'; var\_dump($Malcolm\_Beck`s); echo '</pre>';  
                        
                      array(2) {  
                        ["SELFCODE"]=>  
                        string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("  
                        ["Meaningful"]=>  
                        string(?) "[Der Sinn des Lebens ist deinem Leben einen Sinn zu geben](http://www.youtube.com/watch?v=VS9ecfD0K9c)"  
                      }
                      
                      1. Hi,

                        Vermischung von expliziter und impliziter JOIN-Syntax!

                        Nur eine Verständnisfrage:

                        „Implizit“ ist eine direkte WHERE-Klausel ohne JOIN
                        und
                        „Explizit“ dann mit JOIN?

                        Einen implizten JOIN machst du, wenn du hinter FROM mehr als eine Tabelle, durch Kommata getrennt, aufführst. Der Query-Parser erkennt, dass du Inhalte aus mehreren Tabellen zusammenführen willst, und macht das also auch irgendwie - deshalb implizit.
                        Wie EKKi sagte, kann das aber bspw. Probleme mit der Reihenfolge der Zusammenführungen geben, die man ggf. anders erwartet/angenommen hat.

                        Deshalb ist die explizite Schreibweise zu bevorzugen - wo du die erste Tabelle hinter FROM angibst, und danach explizit, welche Tabellen in welcher Reihenfolge und wie noch hinzugeJOINed werden sollen.

                        Der SELFHTML-Artikel beschreibt das, sowie auch welche Unterschiede es hinsichtlich der Platzierung der Kriterien in der WHERE- oder ON-Klausel gibt.
                        http://aktuell.de.selfhtml.org/artikel/datenbanken/joins/#joins_allgemein

                        MfG ChrisB

                        --
                        Light travels faster than sound - that's why most people appear bright until you hear them speak.
  2. Hallo

    suchst du vielleicht so etwas?

    http://dev.mysql.com/doc/refman/5.1/de/control-flow-functions.html

    viele Grüße
    hawk

  3. Mahlzeit Malcolm Beck´s,

    da Du nicht geschrieben hast, welches DBMS Du verwendest, gehe ich mal von MySQL aus ...

    gibt es so eine art IF für SELECT-Statements, so was wie Bspw:

    Ja.

    IF (optionales_feld) -- Wenn vorhanden

    Eine Spalte ist IMMER vorhanden. Was Du (wahrscheinlich) meinst ist: "wenn die Spalte keinen Wert hat (NULL ist)".

    {
              optionales_feld = 'wert'
            }

    Was funktionieren könnte (das kommt auf Deine genaue Aufgabenstellung an), ist:

    SELECT feld_1  
    ,      feld_2  
    ,      optionales_feld  
      FROM table  
     WHERE feld_1 = 'wert'  
       AND IFNULL(optionales_feld, '') = 'wert'
    

    MfG,
    EKKi

    --
    sh:( fo:| ch:? rl:( br:> n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
    1. hi EKKi,

      da Du nicht geschrieben hast, welches DBMS Du verwendest, gehe ich mal von MySQL aus ...

      Sorry, hatte ich vergessen. Es geht um MySQL.

      » gibt es so eine art IF für SELECT-Statements, so was wie Bspw:
      Ja.

      Das scheint das richtige zu sein, Danke für den Link.

      SELECT feld_1

      ,      feld_2
      ,      optionales_feld
        FROM table
      WHERE feld_1 = 'wert'
         AND IFNULL(optionales_feld, '') = 'wert'

        
      Irgend wie will das bei mir nicht so richtig funktionieren. Das Statement besagt doch --  
        
      `AND IFNULL(optionales_feld, '') = 'wert'`{:.language-sql}  
        
      Wenn in diesem Feld nichts steht, dann dieses Feld nicht mit einbeziehen, oder?  
        
      Ich baue mir aus einträgen in der DB eine Navigation zusammen, ein Versuch mit obigem Beispiel funktioniert nur, wenn in optionales\_feld was steht, ansonsten gibt es NULL.  
      So sieht mein Versuch aus, was mache ich hier falsch?  
        
      ~~~sql
      SELECT  
              link_name, link_target,            -- Hauptlinks für ein Treemenu  
              sub_link_name, sub_link_target     -- Sublinks, werden unter dem jeweilgen Hauptlink eingefügt  
      FROM  
              menu, sub_menu  
      WHERE  
              link_gruppe = 'Hauptmenu'   -- nur die Links, die in die Hauptnavigation eingefügt werden sollen  
      AND  
              IFNULL(parent_id, '') = '" . $dat_verbindung->real_escape_string($URI_Key) . "'  
              -- parent_id ist der Schlüssel, um die Sublinks den jeweiligen Eltern zuzuordnen
      

      Resultat: Wenn es eine parent_id gibt, funktioniert das Statement, wenn es keine parent_id gibt, wird das Statement nicht ausgeführt.

      mfg

      --
      echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
      array(2) {
        ["SELFCODE"]=>
        string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
        ["Meaningful"]=>
        string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
      }
      1. Hi,

        Irgend wie will das bei mir nicht so richtig funktionieren. Das Statement besagt doch --

        AND IFNULL(optionales_feld, '') = 'wert'

        Wenn in diesem Feld nichts steht, dann dieses Feld nicht mit einbeziehen, oder?

        IFNULL gibt den Wert des ersten Ausdrucks zurück, wenn dieser nicht gleich NULL ist, sonst den zweiten.
        Wenn also der Inhalt deines optionales_feld nicht NULL ist, wird dieser zurückgeliefert und mit 'wert' verglichen;
        andernfalls wird '' mit 'wert' verglichen.

        Das ist vermutlich nicht das, was du willst - aber *was* du eigentlich willst, ist mir noch nicht klar geworden.

        Ich baue mir aus einträgen in der DB eine Navigation zusammen, ein Versuch mit obigem Beispiel funktioniert nur, wenn in optionales_feld was steht, ansonsten gibt es NULL.

        Und was *soll* passieren, wenn in optionales_feld "nichts" drin steht?

        Resultat: Wenn es eine parent_id gibt, funktioniert das Statement, wenn es keine parent_id gibt, wird das Statement nicht ausgeführt.

        Dann definiere doch bitte mal, was in den beiden Fällen mit dem Datensatz passieren soll - wann soll er selektiert werden, und wann nicht?

        MfG ChrisB

        --
        Light travels faster than sound - that's why most people appear bright until you hear them speak.
        1. hi,

          IFNULL gibt den Wert des ersten Ausdrucks zurück, wenn dieser nicht gleich NULL ist, sonst den zweiten.
          Wenn also der Inhalt deines optionales_feld nicht NULL ist, wird dieser zurückgeliefert und mit 'wert' verglichen;
          andernfalls wird '' mit 'wert' verglichen.

          Danke für die Erläuterung, jetzt habe ich es verstanden.
          Und Nein, so was suche ich doch nicht.

          Dann definiere doch bitte mal, was in den beiden Fällen mit dem Datensatz passieren soll - wann soll er selektiert werden, und wann nicht?

          Im Grossen und ganzen geht es lediglich darum, die erhaltenen Datensätze in einem Array zu speichern, aus dem später im Script eine HTML-Navigation zusammen gestückelt wird.

          Meine jetzige Lösung ist ein Umweg über 2 SELECTs, mit denen ich die Datensätze einzeln abfrage, daher kam mir die Idee mit einer IF.

          Nehmen wir nochmal mein Beispiel:

          "link_name" und "link_target" sind immer vorhanden, also immer true; die einzige Bedingung ist, dass diese der "link_gruppe" = 'Hauptmenu' angehören.
          Das Resultat speicher ich dann im Array: $HauptLinks[$kategorienRow['link_target']] = $kategorienRow['link_name'];

          SELECT  
                  link_name, link_target,            -- Hauptlinks für ein Treemenu  
                  sub_link_name, sub_link_target     -- Sublinks, werden unter dem jeweilgen Hauptlink eingefügt  
          FROM  
                  menu, sub_menu  
          WHERE  
                  menu.link_gruppe = 'Hauptmenu'   -- nur die Links, die in die Hauptnavigation eingefügt werden sollen  
          
          

          "sub_link_name" und "sub_link_target" sind sozusagen Optional, da nicht jede Seite (Kategorie) unbedingt noch unterseiten haben muss.
          Wenn es "Sublinks" gibt, speicher ich diese auch in einem Array: ~~~php $SubLinks[$kategorienRow['sub_link_target']] = $kategorienRow['sub_link_name'];

          Wenn es keine "Sublinks" gibt, soll die erste WHERE-Klausel trotzdem ausgeführt werden.  
            
            
          Nochmal zur verdeutlichung, um missverständnisse auszuschliessen:  
            
          \-- Kategorie Autos   (Hauptlink)  
          \-- -- VW             (Sublinks)  
          \-- -- BMW            (Sublinks)  
          \-- -- Mercedes       (Sublinks)  
            
          mfg
          
          -- 
          echo '<pre>'; var\_dump($Malcolm\_Beck`s); echo '</pre>';  
            
          array(2) {  
            ["SELFCODE"]=>  
            string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("  
            ["Meaningful"]=>  
            string(?) "[Der Sinn des Lebens ist deinem Leben einen Sinn zu geben](http://www.youtube.com/watch?v=VS9ecfD0K9c)"  
          }
          
          1. Hallo Malcolm,

            Du warst schon mal Lichtjahre weiter, wenn es um die Problembeschreibung bei Datenbankfragen ging.

            » Dann definiere doch bitte mal, was in den beiden Fällen mit dem Datensatz passieren soll - wann soll er selektiert werden, und wann nicht?

            Im Grossen und ganzen geht es lediglich darum, die erhaltenen Datensätze in einem Array zu speichern, aus dem später im Script eine HTML-Navigation zusammen gestückelt wird.

            Meine jetzige Lösung ist ein Umweg über 2 SELECTs, mit denen ich die Datensätze einzeln abfrage, daher kam mir die Idee mit einer IF.

            Nehmen wir nochmal mein Beispiel:

            es folgt unpassender SQL-Code statt Beispieldaten zweier Tabellen und dem gewünschten Ergebnis.

            Möglicherweise ist es ganz einfach, vielleicht wäre es sinnvoll, sich mit dem Nested-Set-Muster vertraut zu machen.

            Freundliche Grüße

            Vinzenz

            1. hi Vinzenz ,

              Du warst schon mal Lichtjahre weiter, wenn es um die Problembeschreibung bei Datenbankfragen ging.

              An sich hielt ich das ganze für eine einfache Frage, es ging ja nur um ein IF in einem SELECT-Statement.

              es folgt unpassender SQL-Code statt Beispieldaten zweier Tabellen und dem gewünschten Ergebnis.

              Habe ich jetzt nachgeholt.

              Möglicherweise ist es ganz einfach, vielleicht wäre es sinnvoll, sich mit dem Nested-Set-Muster vertraut zu machen.

              Ich habe es bestimmt schon 5 mal probiert, da durch zusteigen, aber ich komme mit dem Nested-Set-Model einfach nicht klar.
              Selbst wenn ich die Struktur in der DB hinkriege, muss immer noch ein Code geschrieben werden, der die Daten in Sinnvolles HTML schreibt, und spätestens da geht bei mir dann nichts mehr.

              mfg

              --
              echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
              array(2) {
                ["SELFCODE"]=>
                string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
                ["Meaningful"]=>
                string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
              }
          2. Hi,

            "link_name" und "link_target" sind immer vorhanden, also immer true; die einzige Bedingung ist, dass diese der "link_gruppe" = 'Hauptmenu' angehören.
            Das Resultat speicher ich dann im Array: $HauptLinks[$kategorienRow['link_target']] = $kategorienRow['link_name'];
            [...]
            "sub_link_name" und "sub_link_target" sind sozusagen Optional, da nicht jede Seite (Kategorie) unbedingt noch unterseiten haben muss.
            Wenn es "Sublinks" gibt, speicher ich diese auch in einem Array: ~~~php

            $SubLinks[$kategorienRow['sub_link_target']] = $kategorienRow['sub_link_name'];

              
            Warum reisst du das ganze überhaupt mit Gewalt derart auseinander, in dem du Sachen, die eigentlich zusammengehören, in unterschiedliche Datenobjekte steckst?  
              
            Warum bildest du das (scriptseitig) nicht in einem mehrdimensionalen Array ab?  
              
            Ein Link kann Unterelemente haben oder nicht, wenn ja, dann sind diese in einem Array abgelegt, das wiederum Links enthält, die wiederum Unterelemente haben können oder nicht, ...  
              
            MfG ChrisB  
              
            
            -- 
            Light travels faster than sound - that's why most people appear bright until you hear them speak.
            
            1. hi,

              Warum reisst du das ganze überhaupt mit Gewalt derart auseinander, in dem du Sachen, die eigentlich zusammengehören, in unterschiedliche Datenobjekte steckst?

              Ich bin doch noch in der Lehre ;)

              Ein Link kann Unterelemente haben oder nicht, wenn ja, dann sind diese in einem Array abgelegt, das wiederum Links enthält, die wiederum Unterelemente haben können oder nicht, ...

              Dann hätte ich doch aber wieder das Problem mit dem SELECT-Statement, dem ich sagen müsste,

              Wenn (Unterelemente)
                dann hole die Daten

              ---
              Ich sollte wohl noch mal von vorn anfangen; wie könnte eine mögliche Datenbank-Struktur für ein einfaches Treemenu aussehen?

              Nested-Sets wäre in meinem Fall wohl mit Kanonen auf Spatzen schiessen, denn ich benötige Maximal 3 Ebenen, zumal ich bei Nested-Sets eh nicht durchsteige, selbst nach 5 anläufen.

              Bevor ich wieder in eine Sackgasse laufe, helft mir doch Bitte mal, eine vernünftige Struktur für eine einfache Navigation zu erstellen.

              Mein Ansatz wäre folgender:

              ID  
                
              -- Links der ersten Ebene  
              Titel -- <a>Titel</a>  
              Target -- <a href="/Target">Titel</a>  
                
              -- Links der zweiten Ebene  
              Subtitel -- <a>Subtitel</a>  
              Subtarget -- <a href="/Target/Subtarget">Subtitel</a>  
              ParentId -- Die ID des übergeordneten Links  
                
              -- Möglicher Inhalt  
              ID, Titel, Target, Subtitel, Subtarget, ParentId  
               (1, 'Autos', 'autos', '', '', '')  
              ,(2, '', '', 'BMW', 'bmw', '1')  
              ,(3, '', '', 'VW', 'vw', '1')  
               (4, 'Busse', 'busse', '', '', '')  
              ,(5, '', '', 'Iveco', 'iveco', '4')  
              ,(6, '', '', 'Renault', 'Renault', '4')
              

              Oder wäre das schon vom Ansatz her falsch?

              mfg

              --
              echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
              array(2) {
                ["SELFCODE"]=>
                string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
                ["Meaningful"]=>
                string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
              }
              1. Hi,

                -- Links der ersten Ebene
                Titel -- <a>Titel</a>
                Target -- <a href="/Target">Titel</a>

                -- Links der zweiten Ebene
                Subtitel -- <a>Subtitel</a>
                Subtarget -- <a href="/Target/Subtarget">Subtitel</a>
                ParentId -- Die ID des übergeordneten Links

                -- Möglicher Inhalt
                ID, Titel, Target, Subtitel, Subtarget, ParentId

                Die Unterscheidung in Titel und Subtitel resp. Target und Subtarget sollte überflüssig sein. *Jeder* Link besteht aus einem Titel und einem Target, also können diese Infos auch bei allen Links in den beiden gleichen Spalten hinterlegt werden.

                Die Unterscheidung erste Ebene oder darunter liegende Ebene kannst du allein über die Parent-ID treffen - auf der ersten Ebene haben die Links einfach keine Parent-ID, sondern NULL in diesem Feld stehen; Links auf darunter liegenden Ebenen haben dort die ID ihres Parents.

                MfG ChrisB

                --
                Light travels faster than sound - that's why most people appear bright until you hear them speak.
                1. hi,

                  Die Unterscheidung erste Ebene oder darunter liegende Ebene kannst du allein über die Parent-ID treffen - auf der ersten Ebene haben die Links einfach keine Parent-ID, sondern NULL in diesem Feld stehen; Links auf darunter liegenden Ebenen haben dort die ID ihres Parents.

                  Danke für den Tipp, das klingt Logisch und einfach zu gleich, ich werde mich einfach mal daran versuchen und schauen, wie weit ich alleine komme.

                  mfg

                  --
                  echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
                  array(2) {
                    ["SELFCODE"]=>
                    string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
                    ["Meaningful"]=>
                    string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
                  }
                  1. hi,

                    Danke, Danke und nochmals Danke!

                    Mein erster Ansatz ist nicht gerade Optimal, aber immerhin kann ich die Navigation jetzt bis auf 3 Ebenen aufklappen, ich werde morgen noch versuchen, meinen Ansatz mittels Funktionen zu optimieren, etwas schlanker halten (130 Zeilen -- da sind Locker noch 60 zuviel ;).

                    Aktueller stand: http://dj-tut.de/z_test/selfhtml/menu.php

                    Für Verbesserungsvorschläge bin ich natürlich weiterhin zu haben und Dankbar obendrein ;)

                    mfg

                    --
                    echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
                    array(2) {
                      ["SELFCODE"]=>
                      string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
                      ["Meaningful"]=>
                      string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
                    }
  4. Hi,

    WHERE
            feld_1 = 'wert'
    AND
            IF (optionales_feld) -- Wenn vorhanden
            {
              optionales_feld = 'wert'
            }

    
    >   
    > Wenn ich das Statement ohne IF schreiben würde, bekomme ich kein Resultat, wenn "optionales\_feld\_1" keinen Wert hat.  
    > Dadurch könnte ich mir ein zusätzliches SELECT einsparen, mit dem ich vorher prüfen muss, ob in "optionales\_feld\_1" was steht.  
      
    Wenn es egal sein soll, ob im "optionalen Feld" etwas drinsteht, wieso nimmst du es dann überhaupt in die WHERE-Klausel mit auf?  
      
    MfG ChrisB  
      
    
    -- 
    Light travels faster than sound - that's why most people appear bright until you hear them speak.
    
  5. hi,

    bevor der Thread im Archiv ist nochmal ein Danke schön an alle Helfer!

    mfg

    --
    echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
    array(2) {
      ["SELFCODE"]=>
      string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
      ["Meaningful"]=>
      string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
    }