mike: mysql - COUNT() gibt kein 0 aus

Hallo,

ich habe zwei Tabellen,

"games":
player1 player2 winner looser

1       2       2      1
3       4       3      4

usw...

und

"player":
id

1
2
3
4

usw...

Jetzt will ich die Anzahl der Gewinne für jeden Player ausgeben:

Versucht habe ich es schon wie folgt:

SELECT COUNT(g.winner) AS wins, p.id FROM games g, player p
WHERE g.winner = p.id

Das Problem an der Sache ist, dass der Spieler, der nie gewonnen hat,
im Ergebnis fehlt.

Eventuell wisst ihr, wie ich das machen könnte.
Vielen Dank schon mal,

Mike

  1. Hello,

    Eventuell wisst ihr, wie ich das machen könnte.

    ja, mit einem sauberen LEFT JOIN (oder RIGHT, falls dir das lieber ist...)

    MfG
    Rouven

    --
    -------------------
    sh:| fo:} ch:? rl:( br:& n4:{ ie:| mo:} va:) js:| de:] zu:| fl:( ss:) ls:& (SelfCode)
    Death is nature's way of telling you to slow down.
    1. ja, mit einem sauberen LEFT JOIN (oder RIGHT, falls dir das lieber ist...)

      Ich verstehe gerade nicht den Unterschied zwischen meinem Ansatz und Deinem.

      Könntest du mir genauer erläutern, was dieser an meinem Hauptproblem,
      dem Abfragen "aller" Player ändert?

      Danke für deine Hilfe,
      Mike

      1. Hallo

        ja, mit einem sauberen LEFT JOIN (oder RIGHT, falls dir das lieber ist...)

        nahezu wortwörtlich das gleiche wollte ich gerade abschicken, als ich gerade noch rechtzeitig Rouvens Antwort sah :-)

        Ich verstehe gerade nicht den Unterschied zwischen meinem Ansatz und Deinem.

        Könntest du mir genauer erläutern, was dieser an meinem Hauptproblem,
        dem Abfragen "aller" Player ändert?

        siehe zum Beispiel meine ausführlichen Erläuterungen in folgendem Archivbeitrag zu einem vergleichbaren Problem.

        Freundliche Grüße

        Vinzenz

        1. Ich komm immer noch nicht drauf, hab das noch nie so gemacht:

          SELECT COUNT(g.winner)+1 AS wins, p.id AS playerid FROM players p
          LEFT JOIN games g ON p.id = g.winner GROUP BY playerid

          Funktioniert nicht...

          Hättet ihr noch einen kleinen Tipp?

          Danke, Mike

          1. Hello,

            SELECT COUNT(g.winner)+1 AS wins, p.id AS playerid FROM players p
            LEFT JOIN games g ON p.id = g.winner GROUP BY playerid
            Funktioniert nicht...

            ach das Problem. Ja, da gibts viele Lösungen zu. Anders machen, zum Beispiel.
            Mal im Ernst, was heißt bitte "funktioniert nicht".

            MfG
            Rouven

            --
            -------------------
            sh:| fo:} ch:? rl:( br:& n4:{ ie:| mo:} va:) js:| de:] zu:| fl:( ss:) ls:& (SelfCode)
            Death is nature's way of telling you to slow down.
            1. Mal im Ernst, was heißt bitte "funktioniert nicht".

              OK, die Antwort hab ich schon erwartet, wusste aber nicht, wie ich es am besten beschreiben soll:

              Als Ergebnis bekomme ich nur einen Player zusammen mit der Zahl 3,
              für mich nicht nachvollziehbar...

              sieht man keinen groben Fehler?

              Mike

              1. yo,

                Als Ergebnis bekomme ich nur einen Player zusammen mit der Zahl 3,
                für mich nicht nachvollziehbar...

                ich würde grundsätzlich niemals über einen aliasnamen gruppieren, sondern direkt über den spaltennamen.

                Ilja

                1. ich würde grundsätzlich niemals über einen aliasnamen gruppieren, sondern direkt über den spaltennamen.

                  hab schon beides ausprobiert,
                  aber danke, wusste ich nicht, das man das generell nicht macht.

                  Mike

          2. Hallo

            SELECT COUNT(g.winner)+1 AS wins, p.id AS playerid FROM players p
            LEFT JOIN games g ON p.id = g.winner GROUP BY playerid

            Funktioniert nicht...

            natürlich nicht. Was soll die Addition von 1 bewirken?
            Wie wäre es, wenn Du als allererstes die Liste der Spieler mit der Liste der Gewinner verknüpfst - ohne irgendwelche Zählaktionen, dazu nutzt Du einen INNER JOIN (schöner wäre ein expliziter JOIN statt implizit über eine WHERE-Klausel). Mehr dazu in Rouvens bereits verlinktem Artikel

            Im zweiten Schritt änderst Du die Verknüpfung derart ab, dass auch alle die Spieler mit aufgeführt werden, die noch nicht gewonnen haben. Dazu verwendest Du statt des INNER JOIN einen OUTER JOIN, je nach Gusto einen LEFT oder einen RIGHT JOIN.

            Wenn Du das hast, kannst Du im letzten Schritt zählen, wie oft der einzelne gewonnen hat.

            Wo bist Du hängengeblieben?

            Freundliche Grüße

            Vinzenz

            1. Im zweiten Schritt änderst Du die Verknüpfung derart ab, dass auch alle die Spieler mit aufgeführt werden, die noch nicht gewonnen haben. Dazu verwendest Du statt des INNER JOIN einen OUTER JOIN, je nach Gusto einen LEFT oder einen RIGHT JOIN.

              Hier liegt mein Problem: Wenn ich mit INNER JOIN(implizit oder explitzit):
              "ON g.winner = p.id "
              verknüpfe, fliegen die "Nicht-Gewinner" raus.

              Jetzt habe ich den Ratschlag bekommen, einen LEFT JOIN zu verwenden, weil da kein Datensatz der ersten table verloren geht.
              Dennoch fliegen sie raus... und der Count liefert auch nicht das was er sollte.

              [Das +1 habe ich hinzugefügt, weil ich der Meinung war, wenn der Count null zurückgibt, kein Ergebnis ausgegeben wird]

              Mit welcher spalte (der games table) sollte ich denn jetzt die player-id verknüpfen?
              ("ON g.player1 = p.id OR g.player2 = p.id" habe ich auch schon versucht...)

              Vielen Dank euch allen,
              Mike

              1. yo,

                Dennoch fliegen sie raus... und der Count liefert auch nicht das was er sollte.

                dann hast du den OUTER JOIN nicht richtig geschrieben. bei einen OUTER JOIN können die datensätze der einen tabelle nicht rausfliegen, das ist ja der sinn daran. du solltest erst mal ohne COUNT arbeiten und einfach nur den join bilden und dir dann alle datensätze genau anschauen (dazu kannst du das * benutzen, um alle spalten anzeigen zu lassen), die das dbms zurück gibt. dabei werden einige datensätze in der zweiten tabelle NULL werte haben. das sind eben die spieler datensätze, die nicht in der games tabelle vorhanden sind. und wenn du erkennen kannst, dass er keine spieler ausläßt, dann kannst du sie nach der spieler id gruppieren und mit COUNT zählen lassen.

                [Das +1 habe ich hinzugefügt, weil ich der Meinung war, wenn der Count null zurückgibt, kein Ergebnis ausgegeben wird]

                COUNT gibt niemals NULL werte zurück. der kleinste wert von COUNT ist 0.

                Mit welcher spalte (der games table) sollte ich denn jetzt die player-id verknüpfen?

                wenn du die gewinner haben willst, dann mit der gewinner spalte.

                Ilja