Mot-clé
MAX_BY et MIN_BY
La valeur d'une colonne sur la ligne où une autre colonne est la plus grande (ou la plus petite), dans un simple
GROUP BY.MAX(salary) donne le montant, pas la personne ; MAX_BY(first_name, salary) donne le prénom. Deux MIN dans un
même GROUP BY peuvent venir de lignes différentes : « la page du premier événement », c'est
MIN_BY(page, occurred_at). En cas d'égalité, MAX_BY garde l'une des lignes ex æquo, n'importe laquelle : quand les
égalités comptent, classez avec ROW_NUMBER() OVER (… ORDER BY salary DESC, employee_id) et gardez la ligne 1.
Snowflake, BigQuery, Databricks et Trino l'écrivent MAX_BY / MIN_BY, DuckDB aussi arg_max / arg_min ; Postgres
n'a ni l'un ni l'autre : utilisez-y ROW_NUMBER.
Le piège
SELECT job_title, MAX(salary) AS top_salary, MAX(first_name) AS best_paid
FROM employees
WHERE job_title IN ('Order picker', 'Customer advisor', 'Buyer')
GROUP BY job_title
ORDER BY job_title;
| job_title | top_salary | best_paid |
|---|---|---|
| Buyer | 3100.00 | Nadia |
| Customer advisor | 2450.00 | Thomas |
| Order picker | 2050.00 | Océane |
La correction
SELECT job_title, MAX(salary) AS top_salary,
MAX_BY(first_name, salary) AS best_paid
FROM employees
WHERE job_title IN ('Order picker', 'Customer advisor', 'Buyer')
GROUP BY job_title
ORDER BY job_title;
| job_title | top_salary | best_paid |
|---|---|---|
| Buyer | 3100.00 | Nadia |
| Customer advisor | 2450.00 | Amélie |
| Order picker | 2050.00 | Laura |