sql >> Databasteknik >  >> RDS >> Mysql

Köra flera frågor i MySQL utan att använda sub-query

Det fungerar inte som du tror att det ska och dokumentationen förklarar innebörden av DISTINCT :det handlar om distinkta rader :

(källa:http://dev.mysql.com /doc/refman/5.7/en/select.html )

Du måste gruppera raderna efter användare för att få en enda rad för varje användare, men tyvärr kan du inte få deras senaste poäng på detta sätt. Du kan få högsta, lägsta, genomsnittliga poäng och andra beräknade värden. Kontrollera listan över GROUP BY samla funktioner .

Frågan

Det här är frågan som får de värden du behöver:

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

Så fungerar det

Den förenar tabell användare (alias som u ) med tabell försök (alias som la , förkortning för "sista försök") med e-postadress som matchande kolumn. Det är kopplingen du redan har i din fråga, jag lade till aliasen eftersom de hjälper dig att skriva mindre från den tidpunkten.

Därefter ansluter den till försöken tabell igen (alias som mr från "senare än det senaste försöket"). Det matchar varje försök från la med alla försök från mr för samma användare (identifierad av deras e-postadress ) och som har en nyare datetime . LEFT JOIN säkerställer att varje rad från la matchar minst en rad från mr . Raderna från la som inte har en matchning i mr är de rader som har de största värdena för datetime för varje e-postadress . De matchas med rader fulla av NULL (för mr del).

Slutligen, WHERE satsen behåller endast de rader som har NULL i datetime kolumn i raden som valts från mr . Det här är raderna som matchade de senaste posterna från la för varje värde på e-postadress .

Prestandanmärkningar

För att den här frågan ska kunna köras snabbt (vilken fråga som helst! ) behöver index på kolumnerna som används i JOIN , VAR , GRUPPER EFTER och ORDER BY klausuler.

Du bör inte använda e-postadress i tabellen försök för att identifiera användaren. Du bör ha en PK (primär nyckel) på tabellen användare och använd det som en FK (främmande nyckel) i tabellen försök (och andra tabeller som refererar till en användare). Om e-postadress är PK av tabellen användare ändra det till ett UNIQUE INDEX och använd en ny INTEGER AUTO INCREMENT ed kolumn userId som PK istället. Indexen på numeriska kolumner är snabbare och använder mindre utrymme än indexen på strängkolumner.




  1. Ändra namn på Laravels create_at och updated_at

  2. Skillnaden mellan en användare och en inloggning i SQL Server

  3. skicka parametrar i insert query lagrad procedur i laravel 4

  4. uppdatera kolumnvärden med kolumn i en annan tabell baserat på villkor