Es funktioniert nicht so, wie Sie denken, und die Dokumentation erklärt die Bedeutung von DISTINCT
:Es geht um verschiedene Zeilen :
(Quelle:http://dev.mysql.com /doc/refman/5.7/en/select.html )
Sie müssen die Zeilen nach Benutzern gruppieren, um eine einzelne Zeile für jeden Benutzer zu erhalten, aber leider können Sie auf diese Weise nicht die neueste Punktzahl erhalten. Sie können die maximale, minimale, durchschnittliche Punktzahl und andere berechnete Werte erhalten. Prüfen Sie die Liste von GROUP BY
Aggregatfunktionen
.
Die Abfrage
Dies ist die Abfrage, die die benötigten Werte erhält:
SELECT u.fsname, u.emailaddress, la.score
FROM users u
INNER JOIN attempts la # 'la' from 'last attempt'
ON u.emailaddress = la.emailaddress
LEFT JOIN attempts mr # 'mr' from 'more recent' (than last attempt)
ON la.emailaddress = mr.emailaddress AND la.datetime < mr.datetime
WHERE mr.datetime IS NULL
Wie es funktioniert
Es verbindet die Tabelle users
(alias u
) mit Tabelle attempts
(alias la
, kurz für "letzter Versuch") mit emailaddress
als passende Spalte. Es ist der Join, den Sie bereits in Ihrer Abfrage haben. Ich habe die Aliase hinzugefügt, weil sie Ihnen von diesem Punkt an helfen, weniger zu schreiben.
Als nächstes schließt es sich den attempts
an Tabelle erneut (alias mr
von "neuer als der letzte Versuch"). Es stimmt mit jedem Versuch von la
überein mit all den Versuchen von mr
desselben Benutzers (identifiziert durch ihre emailaddress
). ) und die eine neuere datetime
haben . Der LEFT JOIN
stellt sicher, dass jede Zeile von la
stimmt mit mindestens einer Zeile von mr
überein . Die Zeilen von la
die keine Übereinstimmung in mr
haben sind die Zeilen mit den größten Werten von datetime
für jede emailaddress
. Sie werden mit Zeilen voller NULL
abgeglichen (für den mr
Teil).
Schließlich das WHERE
-Klausel behält nur die Zeilen mit NULL
in der datetime
Spalte der aus mr
ausgewählten Zeile . Dies sind die Zeilen, die mit den neuesten Einträgen von la
übereinstimmen für jeden Wert von emailaddress
.
Leistungsanmerkungen
Um diese Abfrage schnell auszuführen (beliebige Abfrage! ) benötigt Indizes für die im JOIN
verwendeten Spalten , WHERE
, GROUP BY
und ORDER BY
Klauseln.
Sie sollten emailaddress
nicht verwenden in der Tabelle attempts
um den Benutzer zu identifizieren. Sie sollten einen PK
haben (Primärschlüssel) auf Tabelle users
und verwende das als FK
(Fremdschlüssel) in der Tabelle attempts
(und andere Tabellen, die sich auf einen Benutzer beziehen). Wenn emailaddress
ist der PK
der Tabelle users
ändern Sie ihn in einen UNIQUE INDEX
und verwenden Sie ein neues INTEGER AUTO INCREMENT
ed-Spalte userId
als PK
stattdessen. Die Indizes für numerische Spalten sind schneller und benötigen weniger Speicherplatz als die Indizes für Zeichenfolgenspalten.