Nick: [MYSQL] hilfe bei recht komplexer abfrage..

hi,
ich brauche hilfe bei folgender, recht komplexer mysql-abfrage:

select id from foo_data_attributes where (key="type" and value="page") or (select case if (select count(id) from foo_data_attributes where id = *bla*) = 0 then "true" else "false")="true";

foo_data_attributes ist eine tabelle (id (int, nicht eindeutig!), key (tinytext) und value (text)),
in der ich attribute zu daten aus einer anderen tabelle zuordne.
ich habe die tabellen so gestaltet,
um möglichst große freiheit bei der attributenzuordnung zu haben.
*bla* soll hier immer die id vom aktuell geprüften datensatz des äußeren selects sein.
auf deutsch:
hole die spalte id aus foo_data_attributes, wo (key="type" und value="page") ODER wo es zu dieser id kein key="type" gibt.

so will ich annehmen, dass jedes objekt,
das nicht eindeutig als seite gekennzeichnet ist,
automatisch als seite angenommen wird.

was kann ich da für *bla* reinschreiben?

Nick

  1. Hallo,

    was hat dieses a^d ...

    select id from foo_data_attributes where (key="type" and value="page") or (select case if (select count(id) from foo_data_attributes where id = *bla*) = 0 then "true" else "false")="true";

    ... Konstrukt mit dieser ...

    auf deutsch:
    hole die spalte id aus foo_data_attributes, wo (key="type" und value="page") ODER wo es zu dieser id kein key="type" gibt.

    ... Erklärung zu tun. Ich gehe mal davon aus, dass Deine Erklärung in etwa widerspiegelt, was Du haben möchtest :-)

    Alles bis zum ODER sollte kein Problem sein, hast Du ja hinbekommen. Kommen wir nun zum Teil hinter dem ODER:

    Im ersten Schritt verschaffen wir uns die Liste der id-Werte, für die es einen Eintrag in der Spalte key mit dem Wert "type" gibt:

      
    SELECT                     -- Gib mir aus allen Datensätzen alle  
        id                     -- id-Werte  
    FROM                       -- aus der Tabelle  
        foo_data_attributes    -- foo_data_attributes  
    WHERE                      -- die in der Spalte  
        `key` = 'type'         -- key den Wert "type" haben  
    
    

    Wenn in der Liste id-Werte mehrfach auftreten, ist das nicht besonders schlimm. Man könnte mit dem Schlüsselwort DISTINCT dafür sorgen, dass jeder id-Wert nur einmal vorkommt:

      
    SELECT DISTINCT            -- Gib mir die unterschiedlichen  
        id                     -- id-Werte  
    FROM                       -- aus der Tabelle  
        foo_data_attributes    -- foo_data_attributes  
    WHERE                      -- die in der Spalte  
        `key` = 'type'         -- key den Wert "type" haben  
    
    

    Was hilft uns das? Ganz einfach: Du bist genau an den id-Werten interessiert, die *nicht* in dieser Liste stehen. Sowas geht mit SQL und dem Operator NOT IN () wunderbar:

      
    SELECT                              -- Gib mir die Werte  
        fd1.id                          -- der Spalte id  
    FROM                                -- der Tabelle  
        foo_data_attributes fd1         -- foo_data_attributes  
    WHERE (                             -- der Datensätze, die  
            `key` = 'type'              -- in der Spalte key den Wert 'type'  
        AND                             -- und  
            value = 'page'              -- in der Spalte value den Wert 'page' haben  
        )  
        OR                              -- oder  
            fd1.id                      -- deren id  
            NOT IN (                    -- nicht in der  
                SELECT DISTINCT         -- Liste der  
                    fd2.id              -- id-Werte auftaucht  
                FROM                    --  
                    foo_data_attributes fd2  
                WHERE                   -- für die es mindestens einen Datensatz  
                    fd2.`key` = 'type'  -- mit dem Wert type in der Spalte key  
            )                           -- gibt.  
    
    

    scheint mir in etwa das zu sein, was Deiner Erklärung entspricht. Da wir in dieser Abfrage zweimal auf die gleiche Tabelle zugreifen, ist die Verwendung von Aliasnamen sinnvoll.

    Freundliche Grüße

    Vinzenz

    1. hi,
      hast recht, ihc habe mich wohl so ins basteln vertieft, dass ich ganz
      von meinem ursprünglichen problem abgekommen bin; mit (not) in und den
      aliasen hab ich jetzt aber was funktionierendes zusammengebastelt, danke!
      kennt hier jemand ein gutes (my)sql-tutorial, wo man sowas lernt?
      ich finde, die mysql-referenz eignet sich dafür überhauptnicht..

      Nick