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

Ottieni record con valore massimo per ogni gruppo di risultati SQL raggruppati

La soluzione corretta è:

SELECT o.*
FROM `Persons` o                    # 'o' from 'oldest person in group'
  LEFT JOIN `Persons` b             # 'b' from 'bigger age'
      ON o.Group = b.Group AND o.Age < b.Age
WHERE b.Age is NULL                 # bigger age not found

Come funziona:

Corrisponde a ogni riga da o con tutte le righe di b avente lo stesso valore nella colonna Group e un valore maggiore nella colonna Age . Qualsiasi riga da o non avendo il valore massimo del suo gruppo nella colonna Age corrisponderà a una o più righe da b .

Il LEFT JOIN fa corrispondere la persona più anziana del gruppo (comprese le persone che sono sole nel loro gruppo) con una riga piena di NULL s da b ("nessuna età maggiore nel gruppo").
Utilizzo di INNER JOIN rende queste righe non corrispondenti e vengono ignorate.

Il WHERE la clausola mantiene solo le righe con NULL s nei campi estratti da b . Sono le persone più anziane di ogni gruppo.

Ulteriori letture

Questa soluzione e molte altre sono spiegate nel libro SQL Antipatterns:Evitare le insidie ​​della programmazione di database