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

SQL seleziona solo le righe con valore massimo su una colonna

A prima vista...

Tutto ciò di cui hai bisogno è un GROUP BY clausola con il MAX funzione aggregata:

SELECT id, MAX(rev)
FROM YourTable
GROUP BY id

Non è mai così semplice, vero?

Ho appena notato che hai bisogno del content anche colonna.

Questa è una domanda molto comune in SQL:trova tutti i dati per la riga con un valore massimo in una colonna per un identificatore di gruppo. L'ho sentito spesso durante la mia carriera. In realtà, è stata una delle domande a cui ho risposto nel colloquio tecnico del mio attuale lavoro.

In realtà è così comune che la community di Stack Overflow abbia creato un singolo tag solo per affrontare domande del genere: .

Fondamentalmente, hai due approcci per risolvere questo problema:

Unirsi con un semplice group-identifier, max-value-in-group Sottoquery

In questo approccio, trovi prima il group-identifier, max-value-in-group (già risolto sopra) in una sottoquery. Quindi unisci la tua tabella alla sottoquery con uguaglianza su entrambi group-identifier e max-value-in-group :

SELECT a.id, a.rev, a.contents
FROM YourTable a
INNER JOIN (
    SELECT id, MAX(rev) rev
    FROM YourTable
    GROUP BY id
) b ON a.id = b.id AND a.rev = b.rev

Sinistra Unisciti a se stesso, modificando condizioni e filtri di unione

In questo approccio, hai lasciato unire il tavolo con se stesso. L'uguaglianza va nel group-identifier . Poi, 2 mosse intelligenti:

  1. La seconda condizione di unione ha un valore del lato sinistro inferiore al valore di destra
  2. Quando esegui il passaggio 1, le righe che hanno effettivamente il valore massimo avranno NULL nella parte destra (è un LEFT JOIN , ricordare?). Quindi, filtriamo il risultato unito, mostrando solo le righe in cui il lato destro è NULL .

Quindi finisci con:

SELECT a.*
FROM YourTable a
LEFT OUTER JOIN YourTable b
    ON a.id = b.id AND a.rev < b.rev
WHERE b.id IS NULL;

Conclusione

Entrambi gli approcci portano esattamente lo stesso risultato.

Se hai due righe con max-value-in-group per group-identifier , entrambe le righe saranno nel risultato in entrambi gli approcci.

Entrambi gli approcci sono compatibili con SQL ANSI, quindi funzioneranno con il tuo RDBMS preferito, indipendentemente dal suo "sapore".

Entrambi gli approcci sono anche favorevoli alle prestazioni, tuttavia il tuo chilometraggio può variare (RDBMS, struttura DB, indici, ecc.). Quindi, quando scegli un approccio rispetto all'altro, parametro . E assicurati di scegliere quello che ha più senso per te.