Ich stehe ein bisschen auf dem Schlauch - ich habe eine Tabelle mit den Spalten ID, username, hasSolved.
hasSolved kann die Werte 1 (true) oder 0 (false) annehmen.
Es geht um Rätsel, die die User auf meiner Seite gelöst (oder eben nicht gelöst) haben.
Ich möchte nun mit einer Abfrage herausfinden, wer von den Usern die meisten Rätsel gelöst hat (hasSolved also auf 1) und wie viele er gelöst hat.
Nicht ganz…
Hey! Danke für deine Antwort! Es ist allerdings nicht ganz so einfach. Entferne ich nur das LIMIT, dann kriege ich alle User mit der Anzahl ihrer gelösten Rätsel heraus.
Ich möchte aber nur die User haben, die die meisten Rätsel gelöst haben:
Peter hat 1 Rätsel gelöst
Hans hat 2 Rätsel gelöst
Klausi hat 2 Rätsel gelöst
Ergebnis müssten also Hans und Klausi sein (mit 2 gelösten Rätseln - diese Zahl benötige ich ebenfalls)
Ich möchte aber nur die User haben, die die meisten Rätsel
gelöst haben:
dieser Wunsch kann datenbanktechnisch gesehen nicht erfüllt werden. Entweder kriegst Du alle, absteigend sortiert, oder, wenn Dir das nicht gefällt, dann mit LIMIT n eben so viele vordere Plätze wie angegeben.
die Idee ist schon mal gut. Wenn du das LIMIT weglässt, bekommst du alle Benutzernamen und die dazugehörigen Anzahlen der Lösungen:
SELECT COUNT(id) AS cnt, username
FROM quizzes_solved
WHERE hasSolved = 1
GROUP BY username
ORDER BY cnt DESC
Wenn du diese Relation z.B. mit „ranking“ bezeichnest (*), dann kannst du recht einfach die besten herausfinden:
SELECT username
FROM ranking
WHERE cnt = (SELECT max(cnt) FROM ranking)
Gruß
Andreas
(*) Dafür gibt es je nach Datenbanksystem verschiedene Möglichkeiten: Leg eine entsprechende Sicht an, benutze WITH in der Anfrage (common table expression; z.B. bei DB2), ersetze den Namen durch die entsprechende Unteranfrage, etc.
Idee
Folgende Lösung funktioniert, wie gewünscht. Allerdings sieht sie ein bisschen „komisch“ aus - ich denke, es gibt eine elegantere Lösung als diese:
SELECT COUNT(id) AS cnt, user
FROM xmas_quizzes_solved
WHERE solved = 1
GROUP BY user
HAVING cnt = (
SELECT COUNT(id)
FROM xmas_quizzes_solved
WHERE solved = 1
GROUP BY user
ORDER BY COUNT(id) DESC
LIMIT 1
)
Bei relationalen Datenbanken kann man prinzipiell das Ergebnis einer SQL-Anfrage wieder als Eingabe für eine andere SQL-Anfrage benutzen. Ich hatte dir vorgeschlagen, dein Problem auf diese Weise in zwei Teile zu zerlegen: 1. Bestimmung der Anzahl der Lösungen für jeden Benutzer (den Teil hattest du ja schon selbst gefunden); 2. Selektion der Benutzer mit den höchsten Anzahlen.
Folgende Lösung funktioniert, wie gewünscht. Allerdings sieht
sie ein bisschen „komisch“ aus - ich denke, es gibt eine
elegantere Lösung als diese:
SELECT COUNT(id) AS cnt, user
FROM xmas_quizzes_solved
WHERE solved = 1
GROUP BY user
HAVING cnt = (
SELECT COUNT(id)
FROM xmas_quizzes_solved
WHERE solved = 1
GROUP BY user
ORDER BY COUNT(id) DESC
LIMIT 1
)
Falls dein Datenbanksystem „common table expressions“ unterstützt, könntest du so etwas von der Redundanz eliminieren (falls nicht, hast du fast keine Chance, außer mit CREATE VIEW eine Sicht anzulegen):
WITH ranking AS (
SELECT COUNT(id) AS cnt, user
FROM xmas\_quizzes\_solved
WHERE solved = 1
GROUP BY user
)
SELECT cnt, user
FROM ranking
WHERE cnt = (
SELECT cnt
FROM ranking
ORDER BY cnt DESC
LIMIT 1
)
oder etwas schöner mit MAX statt Sortierung + LIMIT:
WITH ranking AS (
SELECT COUNT(id) AS cnt, user
FROM xmas\_quizzes\_solved
WHERE solved = 1
GROUP BY user
)
SELECT cnt, user
FROM ranking
WHERE cnt = (
SELECT MAX(cnt)
FROM ranking
)