SQL cheat sheet (PostgreSQL)
Le istruzioni che ti servono di più, con un esempio per ciascuna. Gli esempi girano sul database di esercizio della panetteria e usano la sintassi di PostgreSQL. Gli altri database differiscono in piccoli dettagli, che vengono segnalati dove contano.
Leggere e filtrare
SELECT sceglie le colonne, FROM indica la tabella, WHERE mantiene le righe che corrispondono, ORDER BY ordina, LIMIT taglia il risultato. Il testo va tra apici singoli.
SELECT name, unit_price FROM products WHERE category = 'pastry' AND unit_price < 3 ORDER BY unit_price DESC LIMIT 5;
Risultato: I prodotti di pasticceria sotto 3.00, dal più caro al meno caro.
Pattern, liste, intervalli e NULL
LIKE confronta schemi (% è qualsiasi testo, _ è un carattere; ILIKE ignora maiuscole e minuscole). IN verifica un elenco, BETWEEN verifica un intervallo inclusivo, IS NULL trova i valori mancanti.
SELECT first_name, loyalty_tier FROM customers WHERE first_name LIKE 'A%' OR loyalty_tier IS NULL ORDER BY first_name;
Risultato: I clienti il cui nome inizia per A, o che non hanno un livello fedeltà.
Riassumere con GROUP BY
COUNT, SUM, AVG, MIN e MAX trasformano le righe in un solo valore per gruppo. WHERE filtra le righe prima del raggruppamento, HAVING filtra i gruppi.
SELECT channel, COUNT(*) AS orders FROM orders GROUP BY channel HAVING COUNT(*) > 5 ORDER BY channel;
Risultato: Solo il canale online, con 7 ordini.
Unire tabelle
INNER JOIN mantiene le corrispondenze, LEFT JOIN mantiene ogni riga della tabella di sinistra. Dai alle tabelle alias brevi e unisci sempre sulla chiave.
SELECT p.name, SUM(oi.quantity) AS units FROM products AS p JOIN order_items AS oi ON oi.product_id = p.product_id GROUP BY p.name ORDER BY units DESC, p.name LIMIT 3;
Risultato: I tre prodotti più venduti.
CASE: if/else in SQL
CASE restituisce il valore della prima condizione vera, come IFS in Excel. Senza ELSE restituisce NULL.
SELECT name,
CASE WHEN unit_price < 3 THEN 'budget' WHEN unit_price <= 4 THEN 'standard' ELSE 'premium' END AS band
FROM products
ORDER BY product_id;Risultato: Ogni prodotto etichettato come budget, standard o premium.
Sottoquery e WITH
Una sottoquery è una query dentro un'altra. WITH le dà un nome, così puoi leggere la query principale come una storia.
WITH spend AS ( SELECT o.customer_id, SUM(oi.quantity * p.unit_price) AS total FROM orders AS o JOIN order_items AS oi ON oi.order_id = o.order_id JOIN products AS p ON p.product_id = oi.product_id GROUP BY o.customer_id ) SELECT customer_id, total FROM spend WHERE total > 30 ORDER BY total DESC;
Risultato: Cliente 1 (Lopez) con 37.10 e cliente 3 (Dubois) con 36.00.
Funzioni finestra
OVER aggiunge un calcolo tra le righe senza raggrupparle: classifiche, totali progressivi, e LAG/LEAD per la riga precedente e quella successiva.
SELECT order_id, order_date,
RANK() OVER (ORDER BY order_date) AS day_rank,
LAG(order_date) OVER (ORDER BY order_id) AS prev_date
FROM orders
ORDER BY order_id;Risultato: Ogni ordine con il suo rango per data e la data dell'ordine precedente.
Modificare i dati
INSERT aggiunge righe, UPDATE le modifica, DELETE le rimuove. Includi sempre WHERE in UPDATE e DELETE, ed eseguine prima una versione SELECT per vedere cosa toccherebbero. Racchiudi le modifiche rischiose tra BEGIN e ROLLBACK.
UPDATE products SET unit_price = unit_price + 0.10 WHERE category = 'drinks' RETURNING name, unit_price;
Risultato: Le due bevande con i nuovi prezzi.
Domande comuni
- In quale ordine esegue SQL una query?
- Prima FROM e JOIN, poi WHERE, GROUP BY, HAVING, SELECT, ORDER BY e infine LIMIT. Per questo un WHERE non può usare un alias di colonna definito in SELECT, mentre ORDER BY sì.
- SQL distingue maiuscole e minuscole?
- Le parole chiave e i nomi di tabelle o colonne no (PostgreSQL converte in minuscolo i nomi senza virgolette). I valori di testo sì: 'Paris' e 'paris' sono diversi, a meno che tu non usi ILIKE o LOWER().
- Funziona in MySQL, SQL Server o SQLite?
- Il nucleo (SELECT, WHERE, GROUP BY, JOIN, CASE) sì. Le differenze stanno in LIMIT (TOP in SQL Server), nella concatenazione di stringhe, nelle funzioni di data e in RETURNING. Per quelle consulta la documentazione del tuo database.