Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Come posso interrogare le classifiche per gli utenti nel mio DB, ma considerare solo l'ultima voce per ciascun utente?

Questo è quello che io chiamo il problema del "più grande n-per-gruppo". Viene visualizzato più volte alla settimana su StackOverflow.

Risolvo questo tipo di problema usando una tecnica di outer join:

SELECT s1.*, s1.wins / s1.losses AS win_loss_ratio
FROM Scrape s1
LEFT OUTER JOIN Scrape s2
  ON (s1.username = s2.username AND s1.ScrapeDate < s2.ScrapeDate)
WHERE s2.username IS NULL
ORDER BY win_loss_ratio DESC;

Questo restituirà solo una riga per ogni nome utente -- la riga con il valore maggiore in ScrapeDate colonna. Ecco a cosa serve l'outer join, da provare per abbinare s1 con qualche altra riga s2 con lo stesso nome utente e una data maggiore. Se non esiste tale riga, il join esterno restituisce NULL per tutte le colonne di s2 , e quindi conosciamo s1 corrisponde alla riga con la data massima per quel nome utente specificato.

Questo dovrebbe funzionare anche quando è in corso uno scraping parzialmente completato.

Questa tecnica non è necessariamente veloce come le soluzioni CTE e RANKING fornite da altre risposte. Dovresti provare entrambi e vedere cosa funziona meglio per te. Il motivo per cui preferisco la mia soluzione è che funziona in qualsiasi versione di SQL.