Il tutorial completo per imparare MySQL da zero: dai database e le tabelle alle query avanzate con JOIN e funzioni. Gli esempi si eseguono nel browser con un motore SQL compatibile.
Introduzione a MySQL
MySQL è uno dei sistemi di gestione di database (DBMS) relazionali più diffusi al mondo, gratuito e open source. È il cuore di moltissimi siti web e applicazioni: è alla base dello stack LAMP (Linux, Apache, MySQL, PHP) e viene gestito spesso tramite l'interfaccia grafica phpMyAdmin.
MySQL usa il linguaggio SQL: tutto ciò che impari qui vale anche per gli altri database relazionali. In questo corso vedremo sia i comandi SQL sia gli aspetti più specifici di MySQL (tipi di dato, AUTO_INCREMENT, funzioni, utenti).
💡 Puoi eseguire le query nel browser: c'è un database di esempio con le tabelle studenti (id, nome, voto, classe, classe_id, citta) e classi (id, aula, classe). Il motore è SQLite, quasi identico a MySQL: dove la sintassi cambia, te lo segnalo.
Esempio
Cos'è un DBMS
Un DBMS (Database Management System) è il software che memorizza, organizza e protegge i dati, permettendo a più utenti e applicazioni di accedervi contemporaneamente in modo sicuro. MySQL è un DBMS relazionale: i dati sono organizzati in tabelle collegate tra loro tramite chiavi.
Database: un contenitore di tabelle (es. il database di una scuola).
Tabella: una griglia di righe e colonne (es. studenti).
Record (riga): una singola voce (es. lo studente Marco).
Campo (colonna): una proprietà (es. il voto).
I tipi di dato in MySQL
Ogni colonna ha un tipo di dato che definisce cosa può contenere. I principali in MySQL:
Categoria
Tipi
Uso
Numerici
INT, DECIMAL, FLOAT
Numeri interi e decimali
Testo
VARCHAR(n), TEXT, CHAR(n)
Stringhe
Data/ora
DATE, DATETIME, TIMESTAMP
Date e orari
Booleani
BOOLEAN (TINYINT)
Vero/falso
💡 Usa VARCHAR per testi di lunghezza variabile (nomi, email) e INT per gli identificatori. Per importi di denaro preferisci DECIMAL a FLOAT per evitare arrotondamenti.
Creare un database: CREATE DATABASE
In MySQL un server può contenere più database. Si crea e si seleziona così (questi comandi si eseguono nel tuo server MySQL/phpMyAdmin, non nell'editor del corso, che lavora su un singolo database già pronto):
MySQL
Creare una tabella: CREATE TABLE
CREATE TABLE definisce una tabella con le sue colonne, i tipi di dato e i vincoli (PRIMARY KEY, NOT NULL, UNIQUE, DEFAULT).
Esempio
AUTO_INCREMENT
Con AUTO_INCREMENT MySQL genera automaticamente un numero progressivo per la chiave primaria a ogni inserimento: non devi indicare tu l'id.
⚙️ In MySQL: id INT AUTO_INCREMENT PRIMARY KEY. In SQLite (l'editor del corso) si usa INTEGER PRIMARY KEY AUTOINCREMENT: il risultato è lo stesso.
Esempio
Inserire dati: INSERT INTO
INSERT INTO aggiunge una o più righe. Puoi inserire più record in un solo comando elencando più gruppi di VALUES.
Esempio
Leggere i dati: SELECT
SELECT legge i dati da una tabella. Con * ottieni tutte le colonne, oppure elenchi quelle desiderate. DISTINCT elimina i duplicati.
Esempio
Filtrare: WHERE
La clausola WHERE filtra le righe con una condizione. Puoi combinare più condizioni con AND, OR e NOT.
Esempio
Ordinare e limitare: ORDER BY e LIMIT
ORDER BY ordina i risultati (ASC/DESC); LIMIT restituisce solo le prime N righe. Insieme servono per le classifiche e la paginazione.
Esempio
Modificare: UPDATE
UPDATE modifica righe esistenti. Ricorda sempre il WHERE, altrimenti aggiorni tutte le righe!
Esempio
Cancellare: DELETE
DELETE elimina righe. Con il WHERE selezioni quali; senza, svuoti la tabella.
Esempio
Le funzioni di aggregazione
Calcolano un valore su più righe: COUNT() conta, SUM() somma, AVG() media, MIN()/MAX() minimo e massimo.
Esempio
LIKE, IN e BETWEEN
LIKE cerca pattern di testo (% = qualsiasi sequenza); IN verifica l'appartenenza a un elenco; BETWEEN seleziona un intervallo.
Esempio
Unire tabelle: JOIN
Il JOIN combina righe di tabelle collegate. Qui uniamo studenti e classi tramite classe_id. INNER JOIN tiene solo le corrispondenze; LEFT JOIN tiene tutte le righe di sinistra.
Esempio
GROUP BY e HAVING
GROUP BY raggruppa le righe per calcolare aggregati per gruppo; HAVING filtra i gruppi (a differenza di WHERE che filtra le righe).
Esempio
Le funzioni stringa
MySQL offre funzioni per manipolare il testo: UPPER(), LOWER(), LENGTH() e CONCAT() per concatenare.
⚙️ In MySQL si concatena con CONCAT(nome, ' - ', citta). Nell'editor del corso (SQLite) si usa l'operatore ||: il risultato è lo stesso.
Esempio
Le funzioni data e ora
MySQL gestisce date e orari con funzioni come NOW() (data e ora attuali), CURDATE() (data odierna) e YEAR(), MONTH(), DAY() per estrarne le parti.
⚙️ In MySQL: SELECT NOW();. Nell'editor (SQLite) l'equivalente è date('now') e datetime('now').
Esempio
Le viste (VIEW)
Una vista è una tabella virtuale basata su una query salvata: la interroghi come una tabella normale. Semplifica le query complesse e le rende riutilizzabili.
Esempio
Gli indici (INDEX)
Un indice accelera le ricerche su una colonna molto usata nei filtri. Migliora le SELECT al prezzo di inserimenti leggermente più lenti.
Esempio
Utenti e privilegi
MySQL gestisce la sicurezza tramite utenti con permessi specifici. Un amministratore crea utenti e assegna loro solo i privilegi necessari (principio del minimo privilegio). Questi comandi si eseguono sul server MySQL reale.
MySQL
MySQL SQL — cos'è
SQL (Structured Query Language) è il linguaggio con cui si parla a MySQL: serve a creare database e tabelle, inserire dati e interrogarli. MySQL è il gestore (DBMS) più diffuso al mondo per le applicazioni web, SQL è il linguaggio che usa.
💡 In questo corso esegui SQL reale direttamente nel browser su un database di esempio con le tabelle studenti (id, nome, voto, classe, classe_id, citta) e classi (id, aula, classe).
MySQL SELECT DISTINCT
SELECT DISTINCT restituisce solo i valori diversi, eliminando i duplicati.
Esempio
MySQL AND, OR, NOT
Gli operatori logici combinano più condizioni nel WHERE: AND (tutte vere), OR (almeno una), NOT (negazione).
Esempio
MySQL Valori NULL
NULL indica un valore mancante, diverso da 0 o da stringa vuota. Si verifica con IS NULL e IS NOT NULL, mai con =.
SELECT * FROM studenti WHERE citta IS NULL;
MySQL LIMIT
LIMIT restringe il numero di righe restituite. È l'equivalente MySQL del SELECT TOP di SQL Server.
Esempio
MySQL MIN() e MAX()
Le funzioni MIN() e MAX() restituiscono il valore più piccolo e più grande di una colonna.
Esempio
MySQL COUNT(), SUM(), AVG()
COUNT() conta le righe, SUM() somma, AVG() calcola la media.
Esempio
MySQL Wildcards
I caratteri jolly si usano con LIKE: % per qualsiasi sequenza, _ per un singolo carattere.
Pattern
Trova
'A%'
Inizia per A
'%a'
Finisce per a
'%ar%'
Contiene "ar"
MySQL IN
L'operatore IN verifica se un valore è in un elenco, in modo più compatto di tanti OR.
Esempio
MySQL BETWEEN
BETWEEN seleziona i valori in un intervallo (estremi inclusi).
Esempio
MySQL Alias
Gli alias (AS) rinominano temporaneamente una colonna o una tabella, rendendo i risultati più leggibili.
Esempio
MySQL INNER JOIN
L'INNER JOIN restituisce solo le righe che hanno corrispondenza in entrambe le tabelle.
Esempio
MySQL LEFT JOIN
Il LEFT JOIN restituisce tutte le righe della tabella di sinistra e le corrispondenze da destra; dove mancano, i campi sono NULL.
SELECT s.nome, c.aula
FROM studenti s
LEFT JOIN classi c ON s.classe_id = c.id;
MySQL RIGHT JOIN
Il RIGHT JOIN è lo specchio del LEFT: tutte le righe della tabella di destra e le corrispondenze da sinistra.
SELECT s.nome, c.aula
FROM studenti s
RIGHT JOIN classi c ON s.classe_id = c.id;
MySQL CROSS JOIN
Il CROSS JOIN combina ogni riga della prima tabella con ogni riga della seconda (prodotto cartesiano). Da usare con attenzione: il numero di righe può esplodere.
SELECT s.nome, c.aula
FROM studenti s
CROSS JOIN classi c;
MySQL SELF JOIN
Un SELF JOIN unisce una tabella a sé stessa usando gli alias, ad esempio per confrontare righe della stessa tabella.
SELECT a.nome AS studente1, b.nome AS studente2, a.citta
FROM studenti a, studenti b
WHERE a.citta = b.citta AND a.id < b.id;
MySQL UNION e UNION ALL
UNION unisce i risultati di due query eliminando i duplicati; UNION ALL li tiene tutti. Le query devono avere lo stesso numero di colonne.
SELECT nome FROM studenti WHERE classe = '3A'
UNION
SELECT nome FROM studenti WHERE voto >= 8;
MySQL HAVING
HAVING filtra i gruppi creati da GROUP BY (mentre WHERE filtra le righe prima del raggruppamento).
Esempio
MySQL EXISTS
EXISTS verifica se una subquery restituisce almeno una riga, restituendo vero o falso.
SELECT aula FROM classi c
WHERE EXISTS (SELECT 1 FROM studenti s WHERE s.classe_id = c.id);
MySQL ANY e ALL
ANY è vero se almeno un confronto con la subquery è vero; ALL se lo sono tutti.
SELECT nome FROM studenti
WHERE voto > ANY (SELECT voto FROM studenti WHERE classe = '3A');
MySQL INSERT INTO SELECT
INSERT INTO SELECT copia righe da una tabella a un'altra già esistente.
INSERT INTO promossi (nome, voto)
SELECT nome, voto FROM studenti WHERE voto >= 6;
MySQL CASE
L'espressione CASE è l'if/else di SQL: restituisce valori diversi secondo le condizioni.
Esempio
MySQL Funzioni per i NULL
In MySQL IFNULL() e COALESCE() forniscono un valore alternativo quando un campo è NULL.
SELECT nome, IFNULL(citta, 'Non indicata') AS citta
FROM studenti;
MySQL Stored Procedures
Una stored procedure è un blocco SQL salvato nel database e richiamabile per nome, anche con parametri.
DELIMITER //
CREATE PROCEDURE StudentiClasse(IN c VARCHAR(10))
BEGIN
SELECT * FROM studenti WHERE classe = c;
END //
DELIMITER ;
CALL StudentiClasse('3A');
MySQL Commenti
I commenti documentano le query: -- o # su una riga, /* ... */ su più righe.
# commento MySQL su una riga
SELECT nome FROM studenti; -- anche così
/* commento
su più righe */
MySQL Operatori
Operatore
Significato
=, <>
Uguale, diverso
>, <, >=, <=
Confronti
AND, OR, NOT
Logici
LIKE, IN, BETWEEN
Ricerca
MySQL DROP DATABASE
DROP DATABASE elimina definitivamente un intero database. Operazione irreversibile.
DROP DATABASE scuola;
⚠️ Prima di un DROP fai sempre un backup del database.
MySQL DROP TABLE
DROP TABLE elimina una tabella con tutti i suoi dati. Per svuotarla mantenendone la struttura si usa invece TRUNCATE TABLE.
DROP TABLE studenti;
MySQL ALTER TABLE
ALTER TABLE modifica la struttura di una tabella esistente: aggiunge, modifica o elimina colonne.
ALTER TABLE studenti ADD email VARCHAR(100);
ALTER TABLE studenti DROP COLUMN email;
MySQL Vincoli (Constraints)
I vincoli definiscono regole sui dati di una colonna per garantirne la correttezza.
Vincolo
Garantisce
NOT NULL
Campo sempre valorizzato
UNIQUE
Valori tutti diversi
PRIMARY KEY
Identificatore univoco
FOREIGN KEY
Collegamento ad altra tabella
CHECK
Condizione sui valori
DEFAULT
Valore predefinito
MySQL NOT NULL
Il vincolo NOT NULL impone che una colonna abbia sempre un valore.
CREATE TABLE studenti (
id INT AUTO_INCREMENT PRIMARY KEY,
nome VARCHAR(50) NOT NULL
);
MySQL UNIQUE
Il vincolo UNIQUE impedisce valori duplicati in una colonna (es. email, matricola).
CREATE TABLE studenti (
id INT AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(100) UNIQUE
);
MySQL PRIMARY KEY
La chiave primaria identifica univocamente ogni riga: è UNIQUE e NOT NULL insieme.
CREATE TABLE studenti (
id INT AUTO_INCREMENT PRIMARY KEY,
nome VARCHAR(50)
);
MySQL FOREIGN KEY
La chiave esterna collega una tabella alla chiave primaria di un'altra, garantendo l'integrità referenziale. È la base delle relazioni in MySQL (motore InnoDB).
CREATE TABLE studenti (
id INT AUTO_INCREMENT PRIMARY KEY,
nome VARCHAR(50),
classe_id INT,
FOREIGN KEY (classe_id) REFERENCES classi(id)
);
MySQL CHECK
Il vincolo CHECK limita i valori ammessi in una colonna a quelli che soddisfano una condizione.
CREATE TABLE studenti (
id INT AUTO_INCREMENT PRIMARY KEY,
voto INT CHECK (voto BETWEEN 1 AND 10)
);
MySQL DEFAULT
Il vincolo DEFAULT assegna un valore predefinito quando non se ne fornisce uno.
CREATE TABLE studenti (
id INT AUTO_INCREMENT PRIMARY KEY,
citta VARCHAR(50) DEFAULT 'Roma'
);
MySQL SQL Injection (sicurezza)
La SQL Injection è una grave vulnerabilità: inserendo codice SQL nei campi di input, un attaccante può leggere o distruggere dati. Mai concatenare l'input dell'utente nelle query!
-- ❌ PERICOLOSO
"SELECT * FROM utenti WHERE nome = '" + input + "'"
-- input = ' OR '1'='1 → l'attaccante entra senza password
⭐ La difesa sono i prepared statements: l'input è trattato come dato, mai come codice.
MySQL Prepared Statements
I prepared statements separano il codice SQL dai dati con dei segnaposto (?), prevenendo la SQL Injection. È il modo corretto di gestire l'input.
PREPARE stmt FROM 'SELECT * FROM studenti WHERE classe = ?';
SET @c = '3A';
EXECUTE stmt USING @c;
💡 In PHP, Python, Java ecc. il valore dei parametri si passa con apposite funzioni (bindParam, execute([...])), non concatenandolo nella stringa.
Esempi MySQL pronti da copiare
Il modo migliore per imparare MySQL è partire da query già funzionanti: copiale, aprile nell'editor “Provalo tu” ed eseguile. Ogni esempio di questo corso è anche un piccolo esercizio.
Media per classe
Editor MySQL online (Provalo tu)
Su questo corso hai un editor SQL online gratuito integrato: esegui query reali direttamente nel browser, senza installare MySQL. Ogni esempio ha il pulsante “Provalo tu ▶”.
Clicca “Provalo tu” su un esempio.
Modifica la query.
Premi ▶ Esegui e guarda la tabella dei risultati.
💡 Per usare MySQL “vero” sul tuo computer installa XAMPP (include MySQL/MariaDB e phpMyAdmin) oppure MySQL Workbench.
Quiz MySQL — metti alla prova le tue conoscenze
Un breve quiz di MySQL per autovalutarti. Pensa alla risposta e poi apri la soluzione.
1. Quale comando crea un nuovo database?
✅ CREATE DATABASE nome;
2. Quale clausola limita il numero di righe in MySQL?
✅ LIMIT (in SQL Server è TOP).
3. Quale attributo genera numeri progressivi automatici?
✅ AUTO_INCREMENT.
4. Come si verifica un campo vuoto?
✅ Con IS NULL, mai con = NULL.
5. Quale motore MySQL supporta le chiavi esterne?
✅ InnoDB (MyISAM non le supporta).
Esercizi MySQL con soluzioni (per principianti)
Questi esercizi di MySQL svolti sono pensati per chi vuole fare pratica con query reali. Per ognuno c'è la consegna e la soluzione commentata: provala nell'editor sul database di esempio (tabelle studenti e classi). Sono gli stessi esercizi di MySQL che assegno ai miei studenti durante le ripetizioni a Roma.
Esercizio 1 — I migliori 3 Base
Mostra i 3 studenti con il voto più alto.
Mostra soluzione
SELECT nome, voto FROM studenti
ORDER BY voto DESC
LIMIT 3;
Esercizio 2 — Studenti di Roma Base
Estrai tutti gli studenti della città di Roma.
Mostra soluzione
SELECT * FROM studenti
WHERE citta = 'Roma';
Esercizio 3 — Conta per città Medio
Conta quanti studenti ci sono per ogni città.
Mostra soluzione
SELECT citta, COUNT(*) AS numero
FROM studenti
GROUP BY citta;
Esercizio 4 — Studenti con aula Medio
Mostra nome studente e aula della sua classe con un INNER JOIN.
Mostra soluzione
SELECT s.nome, c.aula
FROM studenti s
INNER JOIN classi c ON s.classe_id = c.id;
Esercizio 5 — Giudizio con CASE Avanzato
Crea una colonna "giudizio" che vale Ottimo/Sufficiente/Insufficiente in base al voto.
Mostra soluzione
SELECT nome, voto,
CASE
WHEN voto >= 8 THEN 'Ottimo'
WHEN voto >= 6 THEN 'Sufficiente'
ELSE 'Insufficiente'
END AS giudizio
FROM studenti;
⭐ Esegui ogni soluzione nell'editor “Provalo tu” e modificala: è il modo migliore per capire MySQL.
Sfide MySQL — esercizi avanzati senza soluzione
Le sfide MySQL sono esercizi più impegnativi, senza soluzione data: l'obiettivo è ragionare e costruire da soli.
🎯 Sfida 1 — Negozio online
Crea da zero un database per un negozio online: tabelle prodotti, clienti e ordini con le giuste chiavi esterne, poi scrivi una query con JOIN per il fatturato per cliente.
🎯 Sfida 2 — Vista riutilizzabile
Crea una VIEW che mostri solo gli studenti promossi con la loro aula, e interrogala come fosse una tabella.
🎯 Sfida 3 — Procedura con parametro
Scrivi una stored procedure che, dato il nome di una classe, restituisce media, voto minimo e massimo di quella classe.
Programma del corso MySQL (syllabus)
Questo è il programma completo del corso di MySQL, l'elenco ordinato degli argomenti dal principiante all'avanzato. È lo stesso syllabus che seguo in classe e nelle ripetizioni.
Fondamenti: cos'è un RDBMS, tipi di dato, CREATE DATABASE e TABLE.
Dati: INSERT, SELECT, WHERE, ORDER BY, UPDATE, DELETE, LIMIT.
Aggregazione: funzioni aggregate, GROUP BY, HAVING.
Più tabelle: JOIN (inner, left, right, cross, self), UNION, subquery.
Avanzato: stored procedure, utenti, sicurezza e prepared statements.
Piano di studio MySQL
Quanto ci vuole per imparare MySQL? Le basi in una settimana. Ecco un piano di studio realistico studiando circa un'ora al giorno.
Giorno
Cosa studiare
1
RDBMS, tipi di dato, CREATE DATABASE/TABLE
2
INSERT, SELECT, WHERE, ORDER BY
3
UPDATE, DELETE, funzioni aggregate
4
GROUP BY, HAVING, LIKE, IN, BETWEEN
5
JOIN e subquery
6
Vincoli, chiavi, indici, viste
7
Stored procedure, sicurezza, esercizi
Preparazione al colloquio — domande MySQL frequenti
Le domande di MySQL più frequenti ai colloqui per ruoli da sviluppatore backend e data analyst.
Differenza tra MyISAM e InnoDB?
InnoDB supporta transazioni e chiavi esterne; MyISAM è più semplice e veloce in sola lettura ma senza integrità referenziale.
Differenza tra WHERE e HAVING?
WHERE filtra le righe prima del raggruppamento; HAVING filtra i gruppi dopo GROUP BY.
Cosa fa AUTO_INCREMENT?
Genera automaticamente un numero progressivo univoco, tipicamente per la chiave primaria.
Come si previene la SQL Injection?
Con i prepared statements / query parametrizzate, mai concatenando l'input dell'utente.
Bootcamp MySQL — percorso intensivo
Un bootcamp MySQL condensa la teoria nella pratica continua. Per imparare velocemente, alterna ogni argomento con una query da scrivere subito:
✅ Studia un comando (max 20 minuti).
✅ Esegui l'esempio nell'editor “Provalo tu”.
✅ Risolvi un esercizio collegato senza guardare la soluzione.
✅ Ripeti con il comando successivo.
💡 Vuoi un bootcamp MySQL seguito di persona a Roma? Con le ripetizioni in presenza costruiamo insieme un database completo, dalla progettazione alle query avanzate.
Riepilogo MySQL — i concetti chiave
Un riepilogo veloce di MySQL da ripassare prima di una verifica o un colloquio:
📌 MySQL è il DBMS relazionale open source più usato per il web.
📌 Si comanda con il linguaggio SQL: SELECT, INSERT, UPDATE, DELETE.
📌 LIMIT e AUTO_INCREMENT sono tipici di MySQL.
📌 I JOIN uniscono le tabelle tramite le chiavi.
📌 I vincoli e le chiavi garantiscono l'integrità (motore InnoDB).
📌 Usa prepared statements per la sicurezza.
Riferimento — Tipi di dato MySQL
Tipo
Contiene
INT, BIGINT
Numeri interi
DECIMAL, FLOAT
Numeri con decimali
VARCHAR(n), TEXT
Testo
DATE, DATETIME, TIMESTAMP
Date e orari
BOOLEAN (TINYINT)
Vero / falso
Riferimento — Funzioni MySQL
Funzione
Cosa fa
COUNT(), SUM(), AVG()
Aggregazione
CONCAT()
Unisce stringhe
UPPER(), LOWER()
Maiuscolo / minuscolo
NOW(), CURDATE()
Data e ora corrente
IFNULL(), COALESCE()
Gestione dei NULL
ROUND()
Arrotonda un numero
Riferimento — Quick Reference MySQL
Lo schema riassuntivo di una query, nell'ordine in cui si scrivono le clausole:
SELECT colonne
FROM tabella
JOIN altra ON condizione
WHERE condizione
GROUP BY colonna
HAVING condizione_sul_gruppo
ORDER BY colonna
LIMIT n;
Certificato MySQL
Vuoi una certificazione di MySQL da mostrare nel CV? Al termine di questo corso hai le competenze per affrontare i test di certificazione online più diffusi e, soprattutto, per progettare e gestire database reali.
Se sei un mio studente, posso rilasciarti un attestato di partecipazione al percorso di MySQL svolto durante le ripetizioni in presenza a Roma, con l'elenco degli argomenti e dei progetti realizzati.
⭐ Il vero “certificato” è un database ben progettato e funzionante: vale più di qualsiasi attestato.
Conclusione
Complimenti! 🎉 Hai completato il corso di MySQL completo e gratuito in italiano: dai fondamenti dei database relazionali alla creazione di tabelle, dai dati (SELECT, INSERT, UPDATE, DELETE) all'aggregazione e ai JOIN, dai vincoli e le chiavi a viste, indici, stored procedure, utenti e sicurezza, con esercizi, sfide e riferimenti. Ora sai progettare e interrogare un database MySQL.
Il segreto per padroneggiare MySQL è esercitarsi con dati reali: rifai gli esercizi MySQL, affronta le sfide e prova a progettare un database da zero (ad esempio con XAMPP e phpMyAdmin).
E ora?
Il prossimo passo è collegare il database a un'applicazione web con PHP, oppure approfondire la teoria con il corso SQL. Se vuoi un percorso guidato passo passo o aiuto per un progetto o una verifica, posso seguirti con le ripetizioni di informatica in presenza a Roma.
🎯 La tua sfida finale
Crea da zero un database MySQL per un negozio online: tabelle prodotti, clienti e ordini con le giuste chiavi esterne, poi scrivi una query con JOIN per il fatturato per cliente.