ORDER BY trie les lignes renvoyées par une requête selon une ou plusieurs colonnes ou expressions, par ordre croissant ou décroissant. Sans lui, la base de données renvoie les lignes dans l’ordre le plus rapide pour elle. Les exemples fonctionnent sous PostgreSQL, MySQL, SQLite et SQL Server.
Comment utiliser ORDER BY
Place ORDER BY à la fin de la requête, après WHERE, GROUP BY et HAVING ; seul LIMIT vient après. Liste les colonnes de tri. Chacune est triée par ordre croissant, sauf si tu ajoutes DESC :
SELECT columns
FROM table_name
ORDER BY column1 [ASC | DESC], column2 [ASC | DESC];
-- Input: customers
-- customer_id | name | signup_date
-- ------------+-------------+------------
-- 1 | Olivia Hart | 2024-03-12
-- 2 | Marcus Lee | 2023-11-05
-- 3 | Zara Ahmed | 2024-01-27
-- 4 | Ben Carter | 2023-08-19
SELECT customer_id, name, signup_date
FROM customers
ORDER BY signup_date;
-- Output:
-- customer_id | name | signup_date
-- ------------+-------------+------------
-- 4 | Ben Carter | 2023-08-19
-- 2 | Marcus Lee | 2023-11-05
-- 3 | Zara Ahmed | 2024-01-27
-- 1 | Olivia Hart | 2024-03-12
SELECT customer_id, name, signup_date
FROM customers
ORDER BY signup_date DESC;
-- Output:
-- customer_id | name | signup_date
-- ------------+-------------+------------
-- 1 | Olivia Hart | 2024-03-12
-- 3 | Zara Ahmed | 2024-01-27
-- 2 | Marcus Lee | 2023-11-05
-- 4 | Ben Carter | 2023-08-19
Les règles à connaître
-
DESC ne s’applique qu’à la colonne juste avant.
ORDER BY author, published DESCtrie les auteurs de A à Z, puis les livres de chaque auteur du plus récent au plus ancien :
-- Input: books
-- title | author | published
-- --------------------+-----------------+----------
-- Emma | Jane Austen | 1815
-- Bleak House | Charles Dickens | 1853
-- Pride and Prejudice | Jane Austen | 1813
-- Hard Times | Charles Dickens | 1854
SELECT title, author, published
FROM books
ORDER BY author, published DESC;
-- Output:
-- title | author | published
-- --------------------+-----------------+----------
-- Hard Times | Charles Dickens | 1854
-- Bleak House | Charles Dickens | 1853
-- Emma | Jane Austen | 1815
-- Pride and Prejudice | Jane Austen | 1813
-
Sans ORDER BY, l’ordre n’est pas garanti. Les lignes reviennent souvent dans leur ordre d’insertion, jusqu’à ce que la table grossisse, qu’un index change ou que la requête s’exécute en parallèle. C’est vrai aussi pour
LIMIT: sans ORDER BY, il renvoie les premières lignes que la base de données lit. - Les lignes à égalité reviennent dans n’importe quel ordre. Ajoute une colonne unique, comme l’ID, en dernière colonne de tri pour obtenir le même ordre à chaque exécution :
-- Input: customers
-- customer_id | name | signup_date
-- ------------+------------+------------
-- 3 | Mara Lind | 2024-01-15
-- 1 | Owen Price | 2024-01-10
-- 4 | Tariq Aziz | 2024-01-15
-- 2 | Lily Shore | 2024-01-15
-- The three 2024-01-15 rows can come back in any order
SELECT * FROM customers ORDER BY signup_date;
-- Output:
-- customer_id | name | signup_date
-- ------------+------------+------------
-- 1 | Owen Price | 2024-01-10
-- 3 | Mara Lind | 2024-01-15
-- 4 | Tariq Aziz | 2024-01-15
-- 2 | Lily Shore | 2024-01-15
-- customer_id breaks the tie
SELECT * FROM customers ORDER BY signup_date, customer_id;
-- Output:
-- customer_id | name | signup_date
-- ------------+------------+------------
-- 1 | Owen Price | 2024-01-10
-- 2 | Lily Shore | 2024-01-15
-- 3 | Mara Lind | 2024-01-15
-- 4 | Tariq Aziz | 2024-01-15
- Les NULL passent en premier, sauf dans PostgreSQL, qui les met en dernier. Ça vaut pour l’ordre croissant ; DESC inverse le tout :
-- Input: users
-- name | middle_name
-- -----------+------------
-- John Smith | Robert
-- Ana Lopez | NULL
-- Kim Young | Elise
SELECT name, middle_name
FROM users
ORDER BY middle_name;
-- Output:
-- name | middle_name
-- -----------+------------
-- Ana Lopez | NULL
-- Kim Young | Elise
-- John Smith | Robert
-- (PostgreSQL puts Ana Lopez last instead)
Pour choisir où vont les NULL, vois NULLS FIRST et NULLS LAST plus bas.
Syntaxe alternative
Tu peux trier par alias de colonne ou par position de la colonne dans la liste du SELECT. Un alias évite de répéter une expression. Une position est plus courte, mais casse sans prévenir quand quelqu’un modifie la liste du SELECT :
-- Input: employees
-- name | monthly_salary
-- ---------+---------------
-- Ivy Chen | 5200
-- Max Dunn | 7600
-- Pia Roth | 4500
SELECT name, monthly_salary * 12 AS annual_salary
FROM employees
ORDER BY annual_salary DESC; -- or ORDER BY 2 DESC
-- Output:
-- name | annual_salary
-- ---------+--------------
-- Max Dunn | 91200
-- Ivy Chen | 62400
-- Pia Roth | 54000
NULLS FIRST et NULLS LAST après une colonne de tri indiquent où vont ses NULL :
-- Input: the users table above
SELECT name, middle_name
FROM users
ORDER BY middle_name NULLS LAST;
-- MySQL and SQL Server don't support NULLS LAST. Sort on a CASE first instead:
-- ORDER BY CASE WHEN middle_name IS NULL THEN 1 ELSE 0 END, middle_name
-- Output:
-- name | middle_name
-- -----------+------------
-- Kim Young | Elise
-- John Smith | Robert
-- Ana Lopez | NULL
MySQL propose FIELD(), qui trie les valeurs dans l’ordre où tu les listes. Ailleurs, utilise une expression CASE comme celle de Trier des tâches par priorité plus bas :
-- Input: products
-- product_name | category
-- -------------+------------
-- Cookbook | Books
-- Raincoat | Clothing
-- Tablet | Electronics
-- Scarf | Clothing
-- MySQL
SELECT * FROM products
ORDER BY FIELD(category, 'Electronics', 'Clothing', 'Books');
-- Output:
-- product_name | category
-- -------------+------------
-- Tablet | Electronics
-- Raincoat | Clothing
-- Scarf | Clothing
-- Cookbook | Books
Quand utiliser ORDER BY ?
Utilise ORDER BY dès que l’ordre des lignes a un sens pour la personne qui les lit. La plupart des usages entrent dans l’un de ces quatre cas.
Afficher une liste dans un ordre prévisible
Des noms de A à Z, des dates de la plus ancienne à la plus récente, des ID dans l’ordre. Sans ORDER BY, une même requête peut renvoyer ses lignes dans un ordre différent d’une exécution à l’autre, et des pages de résultats peuvent se chevaucher ou sauter des lignes.
Trouver les valeurs les plus élevées ou les plus récentes
Trie par ordre décroissant pour mettre en tête les lignes les plus grandes, récentes ou chères, puis ajoute LIMIT pour ne garder que les premières : meilleures ventes, dernières commandes, meilleurs scores.
Trier par plusieurs colonnes
Quand la première colonne de tri a des égalités, la suivante départage : service puis salaire, niveau puis score, statut puis date. Chaque colonne peut avoir son propre sens de tri.
Trier par une valeur calculée ou un ordre personnalisé
ORDER BY accepte n’importe quelle expression, pas seulement des colonnes : un total calculé à partir de deux colonnes, la longueur d’un nom, ou une expression CASE qui range des valeurs comme High, Medium et Low dans un ordre que l’alphabet ne donne pas.
Exemples concrets d’ORDER BY
Paginer une liste de clients
ORDER BY avec LIMIT et OFFSET renvoie une page à la fois. Trois clients se sont inscrits le même jour, donc customer_id les départage. Sans lui, la base de données pourrait mettre le même client sur les deux pages et en oublier un autre :
-- Input: customers
-- customer_id | name | signup_date
-- ------------+-------------+------------
-- 1 | Nina Brandt | 2024-02-14
-- 2 | Theo Walsh | 2023-09-30
-- 3 | Iris Novak | 2024-02-14
-- 4 | Felix Moore | 2024-02-14
-- 5 | June Park | 2024-03-22
-- Page 1
SELECT customer_id, name, signup_date
FROM customers
ORDER BY signup_date, customer_id
LIMIT 2 OFFSET 0;
-- Output:
-- customer_id | name | signup_date
-- ------------+-------------+------------
-- 2 | Theo Walsh | 2023-09-30
-- 1 | Nina Brandt | 2024-02-14
-- Page 2
SELECT customer_id, name, signup_date
FROM customers
ORDER BY signup_date, customer_id
LIMIT 2 OFFSET 2;
-- SQL Server has no LIMIT: use OFFSET 2 ROWS FETCH NEXT 2 ROWS ONLY
-- Output:
-- customer_id | name | signup_date
-- ------------+-------------+------------
-- 3 | Iris Novak | 2024-02-14
-- 4 | Felix Moore | 2024-02-14
Afficher le top 3 d’un classement
Trie les scores du plus haut au plus bas et garde les trois premiers :
-- Input: players
-- username | score
-- ----------+------
-- quokka42 | 1870
-- nightowl | 2310
-- pixelpete | 1525
-- zara_k | 2045
-- bytebard | 1990
SELECT username, score
FROM players
ORDER BY score DESC
LIMIT 3;
-- SQL Server has no LIMIT: write SELECT TOP 3 username, score instead
-- Output:
-- username | score
-- ---------+------
-- nightowl | 2310
-- zara_k | 2045
-- bytebard | 1990
Créer un rapport de commandes par statut, montant et date
Les statuts sont triés par ordre alphabétique. Dans chaque statut, les plus grosses commandes passent en premier, et à montant égal, les plus récentes d’abord :
-- Input: orders
-- order_id | status | order_value | order_date
-- ---------+------------+-------------+-----------
-- 1001 | Shipped | 120.00 | 2024-03-02
-- 1002 | Delivered | 75.50 | 2024-02-20
-- 1003 | Shipped | 120.00 | 2024-03-05
-- 1004 | Processing | 42.00 | 2024-03-06
-- 1005 | Delivered | 210.00 | 2024-02-28
SELECT order_id, status, order_value, order_date
FROM orders
ORDER BY status ASC, order_value DESC, order_date DESC;
-- Output:
-- order_id | status | order_value | order_date
-- ---------+------------+-------------+-----------
-- 1005 | Delivered | 210.00 | 2024-02-28
-- 1002 | Delivered | 75.50 | 2024-02-20
-- 1004 | Processing | 42.00 | 2024-03-06
-- 1003 | Shipped | 120.00 | 2024-03-05
-- 1001 | Shipped | 120.00 | 2024-03-02
Trier des tâches par priorité
L’ordre alphabétique donnerait High, Low, Medium. Une expression CASE transforme chaque priorité en nombre pour le tri. Tout le reste, ici un NULL, reçoit 4 et passe en dernier, et la date d’échéance ordonne les tâches au sein de chaque priorité :
-- Input: tasks
-- task_name | priority | due_date
-- ---------------+----------+-----------
-- Update docs | Low | 2024-06-03
-- Fix login bug | High | 2024-06-10
-- Plan offsite | NULL | 2024-05-20
-- Renew SSL cert | High | 2024-06-01
-- Review PR | Medium | 2024-06-04
SELECT task_name, priority, due_date
FROM tasks
ORDER BY
CASE priority
WHEN 'High' THEN 1
WHEN 'Medium' THEN 2
WHEN 'Low' THEN 3
ELSE 4
END,
due_date;
-- Output:
-- task_name | priority | due_date
-- ---------------+----------+-----------
-- Renew SSL cert | High | 2024-06-01
-- Fix login bug | High | 2024-06-10
-- Review PR | Medium | 2024-06-04
-- Update docs | Low | 2024-06-03
-- Plan offsite | NULL | 2024-05-20
Pour aller plus loin avec ORDER BY
Sur ce blog :
- Guide de SQL GROUP BY : trier des résultats groupés, comme les catégories qui rapportent le plus
- Guide de l’instruction SQL CASE : des expressions CASE pour des ordres de tri personnalisés
- Limiter les lignes dans PostgreSQL, MySQL, SQLite et SQL Server : LIMIT, OFFSET et TOP
- Sélectionner les N premières lignes dans MySQL : ORDER BY avec LIMIT dans MySQL
-
Guide pour trouver les doublons en SQL : ORDER BY dans
ROW_NUMBER()décide quelle copie compte comme l’originale
Documentation officielle :
- PostgreSQL : trier les lignes (ORDER BY)
- MySQL : trier les lignes
- SQLite : SELECT, la clause ORDER BY
- SQL Server : clause ORDER BY
Beekeeper Studio est une interface de base de données gratuite & open source
Le meilleur outil de requêtes & éditeur SQL que j’aie jamais utilisé. Il m’offre tout ce dont j’ai besoin pour gérer ma base de données. - ⭐⭐⭐⭐⭐ Mit
Beekeeper Studio est rapide, intuitif et facile à utiliser. Beekeeper prend en charge plein de bases de données et fonctionne parfaitement sous Windows, Mac et Linux.
Ce que les utilisateurs disent de Beekeeper Studio
« Beekeeper Studio a complètement remplacé mon ancien workflow SQL. C’est rapide, intuitif, et ça rend le travail sur les bases de données à nouveau agréable. »
« J’ai essayé beaucoup d’interfaces de base de données, mais Beekeeper trouve l’équilibre parfait entre fonctionnalités et simplicité. Ça marche, tout simplement. »