Vinzenz Mai: (MySQL) Gruppierung von Datensätzen, Probleme mit NULL

Beitrag lesen

Hallo,

Nochmal ein Dankeschön für deine Erläuterungen.

bitte, gerne. Ich bin noch nicht fertig.

Jetzt ist mir auch die Funktionsweise von HAVING (wieder) klar.

Ja, ich war verwundert. Ich dachte, Du beherrschtest das :-)

zurück zu Deinem Ausgangsproblem. Du hattest - was gelegentlich vorkommt - Dein Problem zu stark reduziert. Ich füge eine dritte Spalte hinzu, an deren Inhalten Du interessiert bist, so dass Du zwingend die korrelierte Unterabfrage benötigst:

id | wert | name
---+---------+-----
 1 |       9 | Hopsel
 2 |      83 | Vinzenz
 3 |    NULL | dedlfix
 4 |      92 | Sven
 5 |    NULL | Tom
 6 |    NULL | Edgar
 7 |      92 | Chris
 8 |      92 | Steel

Gewünschtes Ergebnis:

id | wert | name
---+---------+-----
 1 |       9 | Hopsel
 2 |      83 | Vinzenz
 3 |    NULL | dedlfix
 4 |      92 | Sven
 5 |    NULL | Tom
 6 |    NULL | Edgar

weil Du innerhalb einer Gruppe mit gleichem und vorhandenem Wert in der Spalte wert nur den Datensatz haben möchtest, der innerhalb der Gruppe die kleinste id aufweist, sowie alle Datensätze, die in der Spalte "wert" den NULL-Wert aufweisen, d.h. keine Daten vorhanden. Außerdem soll aufsteigend nach der Spalte id sortiert werden.

Du wirst sehen, dass Du noch nicht einmal eine UNION benötigst :-)

1. Schritt (korrelierte Unterabfrage)

SELECT                         -- Gib mir  
    t1.id,                     -- id  
    t1.wert,                   -- wert  
    t1.name                    -- und name  
FROM                           -- aus  
    tabelle t1                 -- meiner Tabelle, die hier außen mit t1  
                               -- angesprochen wird,  
WHERE                          -- wobei mich nur die Werte interessieren  
    t1.id = (                  -- bei denen die id gleich  
    SELECT                     -- dem  
        MIN(t2.id)             -- kleinsten id-Wert aus  
    FROM                       -- meiner Tabelle ist, die hier innen mit t2  
        tabelle t2             -- angesprochen wird,  
    WHERE                      -- wobei  
        t1.wert = t2.wert      -- die Werte in der Spalte wert außen wie innen  
)                              -- gleich sein müssen

Aufgrund des speziellen Verhaltens von NULL-Werten: Der Vergleich mit dem Gleichheitsoperator zwischen NULL und NULL liefert NULL.

Tipp dazu: prüfe im Client Deiner Wahl folgendes:

SELECT NULL = NULL test

NULL ist nicht wahr, somit sind Deine Zeilen mit NULL-Werten eh' schon draußen, das Ergebnis dieser Abfrage ist daher (in beliebiger Reihenfolge):

id | wert | name
---+---------+-----
 1 |       9 | Hopsel
 2 |      83 | Vinzenz
 4 |      92 | Sven

2. Schritt:
Es fehlen also noch die Werte mit NULL als wert und die Sortierung.
Wir müssen daher nur noch in der WHERE-Klausel ein

OR t1.wert IS NULL

ergänzen und am Schluß die ORDER-BY-Klausel. Somit erhältst Du:

SELECT  
    t1.id,  
    t1.wert,  
    t1.name  
FROM  
    tabelle t1  
WHERE  
    t1.id = (  
    SELECT  
        MIN(t2.id)  
    FROM  
        tabelle t2  
    WHERE  
        t1.wert = t2.wert  
)  
OR  
    t1.wert IS NULL        -- zu dem Ergebnis aus 1) noch alle Zeilen mit  
                           -- NULL-Werten  
ORDER BY                   -- sortiert  
    t1.id                  -- nach der Spalte id (aufsteigend = Standard)  

als SQL-Statement, das Dir das gewünschte Resultat:

id | wert | name
---+---------+-----
 1 |       9 | Hopsel
 2 |      83 | Vinzenz
 3 |    NULL | dedlfix
 4 |      92 | Sven
 5 |    NULL | Tom
 6 |    NULL | Edgar

liefert.

Freundliche Grüße

Vinzenz