ORDER BY ordina le righe restituite da una query in base a una o più colonne o espressioni, in ordine crescente o decrescente. Senza ORDER BY, il database restituisce le righe nell'ordine per lui più rapido. Gli esempi funzionano in PostgreSQL, MySQL, SQLite e SQL Server.
Come usare ORDER BY
Metti ORDER BY alla fine della query, dopo WHERE, GROUP BY e HAVING; solo LIMIT va dopo. Elenca le colonne in base a cui ordinare. Ognuna viene ordinata in modo crescente, a meno che tu non aggiunga 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
Regole da conoscere
-
DESC si applica solo alla colonna che lo precede.
ORDER BY author, published DESCordina gli autori dalla A alla Z, poi i libri di ciascun autore dal più recente:
-- 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
-
Senza ORDER BY, l'ordine non è garantito. Spesso le righe tornano nell'ordine di inserimento, finché la tabella non cresce, un indice non cambia o la query non viene eseguita in parallelo. Vale anche per
LIMIT: senza ORDER BY restituisce le righe che il database legge per prime. - Le righe a pari merito tornano in un ordine qualsiasi. Aggiungi una colonna univoca, come l'ID, come ultima colonna di ordinamento, così l'ordine è lo stesso a ogni esecuzione:
-- 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
- I NULL vengono ordinati per primi, tranne in PostgreSQL, che li mette per ultimi. Questo vale per l'ordine crescente; DESC lo inverte:
-- 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)
Per scegliere dove mettere i NULL, vedi NULLS FIRST e NULLS LAST più avanti.
Sintassi alternativa
Puoi ordinare in base all'alias di una colonna o alla sua posizione nella lista del SELECT. Un alias ti evita di ripetere un'espressione. Una posizione è più breve, ma si rompe senza avvisi quando qualcuno modifica la lista del 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 e NULLS LAST dopo una colonna di ordinamento indicano dove vanno i suoi 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 ha FIELD(), che ordina i valori nell'ordine in cui li elenchi. Altrove, usa un'espressione CASE come quella in Ordinare le attività per priorità più avanti:
-- 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
Quando usare ORDER BY?
Usa ORDER BY ogni volta che l'ordine delle righe ha un significato per chi le legge. La maggior parte degli usi rientra in uno di questi quattro casi.
Mostrare una lista in un ordine prevedibile
Nomi dalla A alla Z, date dalla più vecchia, ID in sequenza. Senza ORDER BY la stessa query può restituire le righe in un ordine diverso da un'esecuzione all'altra, e le pagine di risultati possono sovrapporsi o saltare righe.
Trovare i valori più alti o più recenti
Ordina in modo decrescente per mettere per prime le righe più grandi, più recenti o più costose, poi aggiungi LIMIT per tenere solo le prime: i più venduti, gli ultimi ordini, i punteggi più alti.
Ordinare per più di una colonna
Quando la prima colonna di ordinamento ha valori a pari merito, la successiva decide l'ordine tra questi: reparto poi stipendio, classe poi punteggio, stato poi data. Ogni colonna può avere la propria direzione.
Ordinare per un valore calcolato o un ordine personalizzato
ORDER BY accetta qualsiasi espressione, non solo colonne: un totale calcolato da due colonne, la lunghezza di un nome o un'espressione CASE che mette valori come High, Medium e Low in un ordine che l'alfabeto non ti darebbe.
Esempi reali di ORDER BY
Sfogliare una lista di clienti
ORDER BY con LIMIT e OFFSET restituisce una pagina alla volta. Tre clienti si sono registrati lo stesso giorno, quindi customer_id risolve il pari merito. Senza, il database potrebbe mettere lo stesso cliente su entrambe le pagine e saltarne un altro:
-- 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
Mostrare i primi tre di una classifica
Ordina i punteggi dal più alto al più basso e tieni i primi tre:
-- 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
Creare un report degli ordini per stato, valore e data
Gli stati sono ordinati alfabeticamente. All'interno di ogni stato vengono prima gli ordini più grandi, e quelli con lo stesso valore mostrano prima i più recenti:
-- 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
Ordinare le attività per priorità
L'ordine alfabetico darebbe High, Low, Medium. Un'espressione CASE trasforma ogni priorità in un numero su cui ordinare. Qualsiasi altro valore, qui un NULL, riceve 4 e va per ultimo, e la data di scadenza ordina le attività all'interno di ogni 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
Altre letture su ORDER BY
Su questo blog:
- Guida a SQL GROUP BY: ordinare risultati raggruppati, come le categorie con più fatturato
- Guida all'istruzione SQL CASE: espressioni CASE per ordinamenti personalizzati
- Limitare le righe in PostgreSQL, MySQL, SQLite e SQL Server: LIMIT, OFFSET e TOP
- Selezionare le prime N righe in MySQL: ORDER BY con LIMIT in MySQL
-
Guida per trovare i duplicati in SQL: ORDER BY dentro
ROW_NUMBER()decide quale copia conta come originale
Documentazione ufficiale:
- PostgreSQL: ordinare le righe (ORDER BY)
- MySQL: ordinare le righe
- SQLite: SELECT, la clausola ORDER BY
- SQL Server: clausola ORDER BY
Beekeeper Studio è una GUI per database gratuita & open source
Il miglior strumento per query & editor SQL che abbia mai usato. Offre tutto ciò che mi serve per gestire il mio database. - ⭐⭐⭐⭐⭐ Mit
Beekeeper Studio è veloce, intuitivo e facile da usare. Beekeeper supporta tantissimi database e funziona alla grande su Windows, Mac e Linux.
Cosa dicono gli utenti di Beekeeper Studio
"Beekeeper Studio ha sostituito completamente il mio vecchio workflow SQL. È veloce, intuitivo e rende di nuovo piacevole lavorare con i database."
"Ho provato tante GUI per database, ma Beekeeper trova l'equilibrio perfetto tra funzionalità e semplicità. Funziona e basta."