Schumiel: MySQL: Count und GROUP BY

Hallo,

folgender SQL-Befehl:

SELECT count(*),verein FROM vereine INNER JOIN setzen ON vereine.verein=setzen=verein GROUP BY verein

Ergibt:

Alle haben die Zahl 1 bei count(*)!

Warum?

Denn ich will, dass wenn der Verein in beiden Tabellen auftritt, das eine 2 da steht. Tritt der Verein in der setzen-Tabelle nicht auf, soll nur eine 1 dastehen!

  1. Denn ich will, dass wenn der Verein in beiden Tabellen auftritt, das eine 2 da steht. Tritt der Verein in der setzen-Tabelle nicht auf, soll nur eine 1 dastehen!

    Schon mal die verschiedenen JOINs ausprobiert?

  2. Hello,

    Denn ich will, dass wenn der Verein in beiden Tabellen auftritt, das eine 2 da steht. Tritt der Verein in der setzen-Tabelle nicht auf, soll nur eine 1 dastehen!

    Da ist count() aber nicht die richtige Wahl.
    Du benöigst einen LEFT OUTER JOIN, wenn Du alle Zeilen aus der linken Tabelle sehen willst und nur die Zeilen aus der rechten, die dazu passen.

    Harzliche Grüße vom Berg
    http://www.annerschbarrich.de

    Tom

    --
    Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
    Nur selber lernen macht schlau

  3. Hallo

    folgender SQL-Befehl:

    SELECT count(*),verein FROM vereine INNER JOIN setzen ON vereine.verein=setzen=verein GROUP BY verein
    Ergibt:
    Alle haben die Zahl 1 bei count(*)!

    Warum?

    Das hängt von Deinen Daten ab. Vereine, die in "setzen" nicht vorkommen, aber in "vereine" werden überhaupt nicht aufgeführt.

    Denn ich will, dass wenn der Verein in beiden Tabellen auftritt, das eine 2 da steht. Tritt der Verein in der setzen-Tabelle nicht auf, soll nur eine 1 dastehen!

    Du kannst das über einen LEFT JOIN lösen. Natürlich weiß ich nicht, ob Vereine in "vereine" oder "setzen" mehr als einmal vorkommen können, dies könnte die Lösung beeinflussen.

    Beispiel:

    Tabelle vereine

    verein
    ------------
    TuS Beispiel
    FC Muster
    VfB Exempel
    SV Test

    Tabelle setzen

    verein
    --------------
    TuS Beispiel
    FC Muster
    SV Test

    1. Schritt:
    Wähle alle Datensätze aus der Tabelle "vereine" aus und ordne die dazu passenden Datensätze aus der Tabelle "setzen" zu, falls vorhanden.

    SELECT  
        v.verein,  
        s.verein  
    FROM verein v  
    LEFT JOIN setzen s  
    ON v.verein = s.verein
    

    ergibt:

    v.verein      | s.verein
    --------------------------
    TuS Beispiel  | TuS Beispiel
    FC Muster     | FC Muster
    VfB Exempel   | NULL          -- kein Wert in Tabelle "setzen"
    SV Test       | SV Test

    -------------------------------------------------------
    2. Schritt:
    Gruppiere nach den Vereinen aus der Tabelle "verein" und
    zähle das Auftreten in "setzen". Beachte die Behandlung
    von NULL-Werten bei Verwendung von COUNT(*) und COUNT(Feldname),
    siehe Handbuch.

    SELECT  
        v.verein,  
        COUNT(s.verein) AS Wert  
    FROM verein v  
    LEFT JOIN setzen s  
    ON v.verein = s.verein  
    GROUP BY v.verein
    

    liefert:

    v.verein      | Wert
    ------------------------
    TuS Beispiel  |  1
    FC Muster     |  1
    VfB Exempel   |  0
    SV Test       |  1

    Mit der einfachen Änderung, dass wir zu Wert jeweils noch 1 dazuaddieren,
    erhältst Du Dein gewünschtes Ergebnis:

    SELECT  
        v.verein,  
        COUNT(s.verein) + 1 AS Wert  
    FROM verein v  
    LEFT JOIN setzen s  
    ON v.verein = s.verein  
    GROUP BY v.verein
    

    liefert:

    v.verein      | Wert
    ------------------------
    TuS Beispiel  |  2
    FC Muster     |  2
    VfB Exempel   |  1
    SV Test       |  2

    ----------------------------------------------------------------------
    3. Schritt:

    Was aber, wenn in der Tabelle "setzen" ein Verein mehrfach auftreten kann?
    Dann sieht das Ergebnis anders aus, als von Dir gewünscht:

    Mit
    Tabelle setzen

    verein
    --------------
    TuS Beispiel
    FC Muster
    TuS Beispiel
    SV Test

    (TuS Beispiel kommt nun zweimal vor) liefert

    SELECT  
        v.verein,  
        s.verein  
    FROM verein v  
    LEFT JOIN setzen s  
    ON v.verein = s.verein
    

    als Ergebnis

    v.verein      | s.verein
    --------------------------
    TuS Beispiel  | TuS Beispiel
    TuS Beispiel  | TuS Beispiel
    FC Muster     | FC Muster
    VfB Exempel   | NULL
    SV Test       | SV Test

    und

    SELECT  
        v.verein,  
        COUNT(s.verein) + 1 AS Wert  
    FROM verein v  
    LEFT JOIN setzen s  
    ON v.verein = s.verein  
    GROUP BY v.verein
    

    ergibt:

    v.verein      | Wert
    ------------------------
    TuS Beispiel  |  3
    FC Muster     |  2
    VfB Exempel   |  1
    SV Test       |  2

    ---------------------------------------------------------------------
    4. Schritt: Lösung dieses Problems mit IF

    Zu dem von Dir vorgegebenen Resultat kannst Du kommen, wenn Du die
    IF-Anweisung einbaust:

    SELECT  
        v.verein,  
        IF (COUNT(s.verein) > 0, 2, 1)  
    FROM verein v  
    LEFT JOIN setzen s  
    ON v.verein = s.verein  
    GROUP BY v.verein
    

    Ergebnis:

    v.verein      | Wert
    ------------------------
    TuS Beispiel  |  2
    FC Muster     |  2
    VfB Exempel   |  1
    SV Test       |  2

    Ganz bestimmt kannst Du die Aufgabe auch mit Subselects lösen, wenn Du MySQL 4.1 oder neuer verwendest - aber das überlasse ich dem interessierten Leser als Übung. Meine Lösung geht sogar noch mit MySQL 3.23 :-)

    Freundliche Grüße

    Vinzenz

    1. boah Vinz,

      ich staune immer wieder über deinen fleiss und sorgfalt bei deinen antworten. ich muss gestehen, dass ich Schumiel, faul wie ich nun mal bin, gefragt hätte, in welcher beziehung die beiden tabellen zueinander stehen, bevor ich auch nur eine lösung präsentiert hätte (count oder if). Und du gehst hier gleich alle eventualitäten durch.

      nicht dass du mir die kundschaft zu sehr verwöhnst. ;-)

      Ilja

    2. Danke, habe kurz drüber gestöbert und eine SQL-Anweisung ist dabei die bei dir so funktionieren soll? Denn ich hab's genauso und bekomme keine 0 zurück. ich teste dann gleich nochmal!