Mysql
 sql >> Database >  >> RDS >> Mysql

Esecuzione di più query in MySQL senza utilizzare sottoquery

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.