f in x
SQL Fondamentali: SELECT, FROM, WHERE, JOIN, GROUP BY — Guida Pratica con Esempi Reali
> cd .. / HUB_EDITORIALE > Visualizza in Inglese
Analisi dei dati e metriche

SQL Fondamentali: SELECT, FROM, WHERE, JOIN, GROUP BY — Guida Pratica con Esempi Reali

[2026-05-29] Author: Ing. Calogero Bono

Hai un database pieno di ordini, clienti e prodotti, ma ogni volta che provi a estrarre un report ti ritrovi con dati sbagliati o una pagina che non finisce mai di caricare? Oppure ti hanno appena affidato un vecchio gestionale e devi tirare fuori il fatturato per categoria, ma non sai da che parte iniziare? Noi di Meteora Web ci siamo passati. Seguiamo aziende dal 2017: dal dominio al fatturato, un unico interlocutore. E quando parliamo di SQL, lo facciamo partendo dai problemi veri — non dalla teoria dei database.

Questa guida ti porta dritto al punto: SELECT, FROM, WHERE, JOIN e GROUP BY. Cinque istruzioni che, usate bene, ti danno il 90% delle risposte che un'azienda chiede al suo database. Vediamole con esempi reali, quelli che incontri ogni giorno in un e-commerce o in un sistema gestionale.

1. SELECT e FROM — La base che pochi sfruttano fino in fondo

Partiamo da un caso concreto: hai una tabella ordini. Vuoi vedere tutti gli ordini dell'ultimo mese. Scrivi:

SELECT * FROM ordini WHERE data_ordine >= '2025-01-01';

Funziona, ma SELECT * è quasi sempre un errore. Quando lavori su un database reale con decine di colonne e migliaia di righe, tirare giù tutto rallenta la rete, riempie la memoria e rischia di esporre dati sensibili (es. costi, password hash). Noi abbiamo visto clienti con query che impiegavano 30 secondi solo per selezionare 10 colonne inutili.

Regola pratica: seleziona solo le colonne che ti servono. In un report vendite, ti servono id_ordine, data, totale, cliente_id. Niente di più.

SELECT id_ordine, data_ordine, totale, cliente_id
FROM ordini
WHERE data_ordine >= '2025-01-01';

Se devi rinominare una colonna per chiarezza, usa alias (AS).

SELECT totale AS importo_totale, cliente_id AS id_cliente
FROM ordini;

È un'abitudine che paga: report più puliti, query più veloci, minori rischi di errore.

Operatività immediata

Prendi una delle tue tabelle più usate e riscrivi una query sostituendo SELECT * con i nomi delle colonne reali che ti servono. Nota la differenza di tempo di esecuzione se hai molti dati.

2. WHERE — Filtrare con precisione (e senza errori)

Il WHERE è il tuo setaccio. Ma è facile sbagliare. L'errore più comune? Dimenticare le virgolette per le stringhe o usare = al posto di LIKE per ricerche parziali.

Scenario reale: devi trovare tutti gli ordini di un cliente di nome "Mario Rossi". Ma nel database il nome potrebbe essere scritto "Rossi Mario" o "Mario" da solo. WHERE nome_cliente = 'Mario Rossi' non basta.

SELECT * FROM clienti WHERE nome LIKE '%Mario%' AND cognome LIKE '%Rossi%';

Il % è un wildcard: significa "qualsiasi carattere prima o dopo". Attenzione: LIKE '%Mario%' è più lento su grandi tabelle perché non usa indici. Se la ricerca è frequente, valuta un indice full-text o una colonna normalizzata.

Un altro errore comune: filtrare su date come stringhe. Meglio usare il formato standard YYYY-MM-DD e confrontare con operatori >=, <.

SELECT * FROM ordini
WHERE data_ordine BETWEEN '2025-01-01' AND '2025-01-31';

Nota importante: se la colonna contiene anche ore, BETWEEN include la data finale fino a mezzanotte. Per intervalli precisi, usa >= e <.

Operatività immediata

  • Controlla se qualche tua query usa WHERE campo = 'valore' su stringhe che potrebbero avere spazi o maiuscole. Aggiungi TRIM() e LOWER() se necessario.
  • Verifica le condizioni sulle date: sono confrontate come stringhe o come date? Se sono stringhe, converti il campo con DATE().

3. JOIN — Quando i dati vivono in tavoli diversi

Il database di un e-commerce non mette tutto in una tabella. Hai ordini, clienti, prodotti, righe_ordine. Per ottenere un report "nome cliente, totale ordine, prodotti acquistati" devi unire le tabelle.

Il JOIN più usato è INNER JOIN: restituisce solo le righe che hanno corrispondenza in entrambe le tabelle.

SELECT c.nome, o.id_ordine, o.totale
FROM clienti c
INNER JOIN ordini o ON c.id_cliente = o.cliente_id
WHERE o.data_ordine >= '2025-01-01';

Attenzione agli alias: usa lettere brevi (c, o) ma chiare. Se hai 5 join, diventa illeggibile.

LEFT JOIN è il secondo più comune: restituisce tutte le righe della tabella di sinistra, e se non c'è corrispondenza mette NULL. Esempio: lista di tutti i clienti con i loro ultimi ordini (anche chi non ha mai ordinato).

SELECT c.nome, MAX(o.data_ordine) AS ultimo_ordine
FROM clienti c
LEFT JOIN ordini o ON c.id_cliente = o.cliente_id
GROUP BY c.id_cliente;

Noi di Meteora Web abbiamo visto errori tipici: dimenticare la condizione di join (scrivere FROM clienti, ordini senza ON genera un prodotto cartesiano esplosivo). Oppure usare LEFT JOIN quando serve INNER JOIN (e viceversa). Regola: se vuoi solo i clienti che hanno ordini, usa INNER; se vuoi tutti i clienti, LEFT.

Operatività immediata

Prendi la tua query più complessa con join e controlla: ogni JOIN ha la sua ON? Hai dimenticato un LEFT? Prova a rimuovere un join uno alla volta per vedere cosa succede al risultato.

4. GROUP BY — Aggregare senza perdere il controllo

Il GROUP BY serve a riassumere: totale vendite per mese, numero ordini per cliente, media spesa per categoria. Ma è anche dove si annidano gli errori più subdoli.

Errore classico: mettere in SELECT una colonna che non è né aggregata né raggruppata. Molti database (come MySQL con sql_mode=ONLY_FULL_GROUP_BY disabilitato) lo permettono, ma il risultato è imprevedibile — prende un valore a caso.

Esempio corretto: vogliamo il totale ordini e il numero di ordini per ogni cliente.

SELECT cliente_id, COUNT(*) AS numero_ordini, SUM(totale) AS totale_speso
FROM ordini
GROUP BY cliente_id;

Se vuoi filtrare dopo l'aggregazione (es. solo clienti che hanno speso più di 1000€), non usare WHERE ma HAVING.

SELECT cliente_id, SUM(totale) AS totale_speso
FROM ordini
GROUP BY cliente_id
HAVING totale_speso > 1000;

Differenza cruciale: WHERE filtra le righe prima del GROUP BY, HAVING dopo. Se usi WHERE con una funzione aggregata, il database ti darà errore.

Operatività immediata

  • Controlla le tue query con GROUP BY: tutte le colonne non aggregate sono elencate nel GROUP BY? Se no, riscrivi.
  • Prova a tradurre una WHERE che filtra su una somma in HAVING.

5. Metti tutto insieme — Un esempio reale da e-commerce

Immagina un negozio di abbigliamento (come quello che abbiamo gestito dall'interno con l'ERP). Vuoi sapere, per ogni categoria di prodotto, quanti pezzi sono stati venduti e il fatturato lordo nel mese di gennaio 2025, ma solo per i clienti che hanno speso almeno 50€ in totale.

SELECT cat.nome_categoria,
       COUNT(rp.id_riga) AS pezzi_venduti,
       SUM(rp.prezzo * rp.quantita) AS fatturato
FROM righe_prodotti rp
JOIN prodotti p ON rp.prodotto_id = p.id_prodotto
JOIN categorie cat ON p.categoria_id = cat.id_categoria
JOIN ordini o ON rp.ordine_id = o.id_ordine
JOIN clienti c ON o.cliente_id = c.id_cliente
WHERE o.data_ordine BETWEEN '2025-01-01' AND '2025-01-31'
  AND (SELECT SUM(o2.totale) FROM ordini o2 WHERE o2.cliente_id = c.id_cliente) >= 50
GROUP BY cat.id_categoria, cat.nome_categoria
ORDER BY fatturato DESC;

Questa query usa JOIN su 5 tabelle, WHERE con subquery, GROUP BY e ORDER BY. È un esempio reale che puoi adattare al tuo database.

Nota sulle performance: la subquery nel WHERE viene eseguita per ogni riga del join. Su milioni di righe, potrebbe essere lenta. Una soluzione migliore è calcolare prima il totale per cliente con una CTE o una tabella temporanea, ma questa è una guida introduttiva — arriveremo a quello.

In sintesi — cosa fare adesso

  1. Riscrivi le tue SELECT * in selezioni mirate. Prendi una query di report che usi spesso e sostituisci * con le colonne necessarie. Misura il tempo prima e dopo.
  2. Verifica i WHERE: le stringhe hanno virgolette? Le date sono confrontate come date? Aggiungi BETWEEN o >= e < per intervalli precisi.
  3. Esamina i JOIN della tua applicazione. Ogni JOIN ha una chiave di relazione? Stai usando INNER o LEFT a seconda della necessità? Controlla che non ci siano prodotti cartesiani accidentali.
  4. Rivedi ogni GROUP BY: tutte le colonne non aggregate nel SELECT sono elencate nel GROUP BY? Se hai filtri su aggregati, usa HAVING invece di WHERE.
  5. Fai pratica con un database campione. Scarica il database di esempio employees di MySQL o usa un tuo dump. Scrivi 5 query che combinano SELECT, FROM, WHERE, JOIN, GROUP BY con HAVING e ORDER BY. Più scrivi, più interiorizzi.

Noi di Meteora Web lavoriamo con aziende che spesso scoprono queste basi solo quando il sito va in crash o il report non torna. Se vuoi evitarlo, inizia oggi. Il database è il cuore del tuo business: trattalo con rispetto.

Sponsored Protocol

Ing. Calogero Bono

> AUTHOR_EXTRACTED

Ing. Calogero Bono

Co-founder di Meteora Web. Ingegnere informatico, sviluppo ecosistemi digitali ad alte prestazioni. AI, automazione, SEO tecnica e infrastrutture web. Scrivo di tecnologia per rendere complesso… semplice.

[ Read Full Dossier ]

Hai bisogno di applicare questa strategia?

Esegui il protocollo di contatto per iniziare un progetto con noi.

> INIZIA_PROGETTO

Sponsored

> MW_JOURNAL

> READ_ALL()