Het werkt niet zoals je denkt dat het zou moeten en de documentatie verklaart de betekenis van DISTINCT
:het gaat om verschillende rijen :
(bron:http://dev.mysql.com /doc/refman/5.7/nl/select.html )
U moet de rijen per gebruiker groeperen om een enkele rij voor elke gebruiker te krijgen, maar helaas kunt u op deze manier hun meest recente score niet krijgen. U kunt de maximale, minimale, gemiddelde score en andere berekende waarden krijgen. Bekijk de lijst met GROUP BY
geaggregeerde functies
.
De vraag
Dit is de query die de gewenste waarden ophaalt:
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
Hoe het werkt
Het voegt zich bij tabel users
(alias u
) met tabel attempts
(alias la
, een afkorting voor "laatste poging") met behulp van emailaddress
als de overeenkomende kolom. Het is de join die je al hebt in je zoekopdracht, ik heb de aliassen toegevoegd omdat ze je vanaf dat moment helpen minder te schrijven.
Vervolgens voegt het zich bij de attempts
tabel opnieuw (alias mr
) van "meer recent dan de laatste poging"). Het komt overeen met elke poging van la
met alle pogingen van mr
van dezelfde gebruiker (geïdentificeerd door hun emailaddress
) en die een recentere datetime
. hebben . De LEFT JOIN
zorgt ervoor dat elke rij van la
komt overeen met ten minste één rij van mr
. De rijen van la
die geen overeenkomst hebben in mr
zijn de rijen met de grootste waarden van datetime
voor elk emailaddress
. Ze worden gekoppeld aan rijen vol met NULL
(voor de mr
deel).
Eindelijk, de WHERE
clausule behoudt alleen de rijen die NULL
. hebben in de datetime
kolom van de rij geselecteerd uit mr
. Dit zijn de rijen die overeenkwamen met de meest recente invoer van la
voor elke waarde van emailaddress
.
Opmerkingen over prestaties
Om deze zoekopdracht snel uit te voeren (elke zoekopdracht! ) heeft indexen nodig voor de kolommen die worden gebruikt in de JOIN
, WHERE
, GROUP BY
en ORDER BY
clausules.
Gebruik geen emailaddress
in tabel attempts
om de gebruiker te identificeren. Je zou een PK
. moeten hebben (primaire sleutel) op tafel users
en gebruik dat als een FK
(vreemde sleutel) in tabel attempts
(en andere tabellen die naar een gebruiker verwijzen). Als emailaddress
is de PK
van tabel users
verander het in een UNIQUE INDEX
en gebruik een nieuwe INTEGER AUTO INCREMENT
ed kolom userId
als PK
in plaats van. De indexen op numerieke kolommen zijn sneller en nemen minder ruimte in beslag dan de indexen op stringkolommen.