Non funziona come pensi che dovrebbe e la documentazione spiega il significato di DISTINCT
:si tratta di righe distinte :
(fonte:http://dev.mysql.com /doc/refman/5.7/en/select.html )
È necessario raggruppare le righe per utente per ottenere una singola riga per ogni utente ma, sfortunatamente, non è possibile ottenere il punteggio più recente in questo modo. È possibile ottenere il punteggio massimo, minimo, medio e altri valori calcolati. Controlla l'elenco di GROUP BY
funzioni aggregate
.
La domanda
Questa è la query che ottiene i valori di cui hai bisogno:
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
Come funziona
Si unisce alla tabella users
(alias u
) con la tabella attempts
(alias la
, abbreviazione di "ultimo tentativo") utilizzando emailaddress
come colonna corrispondente. È il join che hai già nella tua query, ho aggiunto gli alias perché ti aiutano a scrivere meno da quel momento in poi.
Successivamente, si unisce ai attempts
di nuovo la tabella (alias mr
da "più recenti rispetto all'ultimo tentativo"). Corrisponde a ogni tentativo da la
con tutti i tentativi di mr
dello stesso utente (identificato dal suo emailaddress
) e che hanno un datetime
più recente . Il LEFT JOIN
assicura che ogni riga da la
corrisponde ad almeno una riga da mr
. Le righe da la
che non hanno una corrispondenza in mr
sono le righe che hanno i valori maggiori di datetime
per ogni emailaddress
. Sono abbinati a righe piene di NULL
(per il mr
parte).
Infine, il WHERE
la clausola mantiene solo le righe che hanno NULL
nel datetime
colonna della riga selezionata da mr
. Queste sono le righe che corrispondono alle voci più recenti di la
per ogni valore di emailaddress
.
Note sul rendimento
Per eseguire velocemente questa query (qualsiasi query! ) necessita di indici sulle colonne utilizzate in JOIN
, WHERE
, GROUP BY
e ORDER BY
clausole.
Non dovresti usare emailaddress
nella tabella attempts
per identificare l'utente. Dovresti avere un PK
(chiave primaria) sulla tabella users
e usalo come FK
(chiave straniera) nella tabella attempts
(e altre tabelle che fanno riferimento a un utente). Se emailaddress
è il PK
della tabella users
cambialo in un UNIQUE INDEX
e usa un nuovo INTEGER AUTO INCREMENT
ed colonna userId
come PK
invece. Gli indici sulle colonne numeriche sono più veloci e occupano meno spazio rispetto agli indici sulle colonne stringa.