Cela ne fonctionne pas comme vous le pensez et la documentation explique la signification de DISTINCT
:il s'agit de lignes distinctes :
(source :http://dev.mysql.com /doc/refman/5.7/en/select.html )
Vous devez regrouper les lignes par utilisateur afin d'obtenir une seule ligne pour chaque utilisateur mais, malheureusement, vous ne pouvez pas obtenir leur score le plus récent de cette façon. Vous pouvez obtenir le score maximum, minimum, moyen et d'autres valeurs calculées. Consultez la liste des GROUP BY
fonctions d'agrégation
.
La requête
Voici la requête qui obtient les valeurs dont vous avez besoin :
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
Comment ça marche
Il joint la table users
(alias u
) avec le tableau attempts
(alias la
, abréviation de "dernière tentative") en utilisant emailaddress
comme colonne correspondante. C'est la jointure que vous avez déjà dans votre requête, j'ai ajouté les alias car ils vous aident à écrire moins à partir de ce moment.
Ensuite, il rejoint les attempts
table à nouveau (alias mr
de "plus récent que la dernière tentative"). Il correspond à chaque tentative de la
avec toutes les tentatives de mr
du même utilisateur (identifié par son emailaddress
) et qui ont un datetime
plus récent . Le LEFT JOIN
garantit que chaque ligne de la
correspond à au moins une ligne de mr
. Les lignes de la
qui n'ont pas de correspondance dans mr
sont les lignes qui ont les plus grandes valeurs de datetime
pour chaque emailaddress
. Ils sont mis en correspondance avec des lignes pleines de NULL
(pour le mr
partie).
Enfin, le WHERE
clause ne conserve que les lignes qui ont NULL
dans le datetime
colonne de la ligne sélectionnée à partir de mr
. Ce sont les lignes qui correspondent aux entrées les plus récentes de la
pour chaque valeur de emailaddress
.
Remarques sur les performances
Afin d'exécuter rapidement cette requête (n'importe quelle requête ! ) a besoin d'index sur les colonnes utilisées dans le JOIN
, WHERE
, GROUP BY
et ORDER BY
clauses.
Vous ne devez pas utiliser emailaddress
dans le tableau attempts
pour identifier l'utilisateur. Vous devriez avoir un PK
(clé primaire) sur la table users
et l'utiliser comme FK
(clé étrangère) dans la table attempts
(et autres tableaux faisant référence à un utilisateur). Si emailaddress
est le PK
de la table users
changez-le en un UNIQUE INDEX
et utilisez un nouveau INTEGER AUTO INCREMENT
ed colonne userId
comme PK
Au lieu. Les index sur les colonnes numériques sont plus rapides et utilisent moins d'espace que les index sur les colonnes de chaîne.