Meiste Einträge

Hey!

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.

Danke schon mal
Gruß Christoph

Idee
Folgendes macht schon fast genau das, was es soll. Der User mit den meisten gelösten Rätseln wird mir ausgegeben:

SELECT COUNT(id) AS cnt, username
FROM quizzes_solved
WHERE hasSolved = 1
GROUP BY username
ORDER BY cnt DESC
LIMIT 1

Aber was ist, wenn 2 User (oder auch 3) gleich viele Rätsel gelöst haben?
Wie muss die Anfrage aussehen, damit alle ausgegeben werden?

Danke und Gruß
Christoph

Moin, Christoph,

Wie muss die Anfrage aussehen, damit alle ausgegeben werden?

lass das LIMIT weg, dann kommen sie alle.

Gruß Ralf

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)

Danke und Gruß
Christoph

Hi Christoph,

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.

Gruß Ralf

Nachtrag

mit LIMIT n eben so viele
vordere Plätze wie angegeben.

bei mir (Access) heißt das nicht LIMIT, sondern TOP - ich hoffe, dass wir da vom Gleichen sprechen :smile:

Hi,

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.

  1. 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
)

Gruß Christoph

Ich verstehe leider nicht, was du meinst.
Wie muss ich vorgehen?

Ich verstehe leider nicht, was du meinst.

Was genau verstehst du denn nicht?

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.

Andreas

Hallo Christoph,

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
)

Andreas

ERLEDIGT
Ahh, super - danke!
Ein Stück Code sagt manchmal mehr, als 1000 Worte :smiley:

Gruß Christoph