Vinzenz Mai: [MYSQL] hilfe bei recht komplexer abfrage..

Beitrag lesen

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