Mysql
 sql >> Base de données >  >> RDS >> Mysql

Exécuter plusieurs requêtes dans MySQL sans utiliser de sous-requête

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.