Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Ausführen mehrerer Abfragen in MySQL ohne Verwendung von Unterabfragen

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.