Vai al contenuto
SDETRole
SDETRole

Impara / Cheat sheet

Cheat sheet SQL per tester

L’SQL che i tester usano per verificare i dati dietro una UI o un’API: trovare il record, controllare che sia cambiato e cercare duplicati, record orfani e NULL che non dovrebbero esserci. La sintassi è SQL standard e funziona su PostgreSQL, MySQL 8 e SQLite. Dove un database si comporta diversamente, la nota lo segnala.

Verificato su SQL standard; verificato su PostgreSQL 16, MySQL 8 e SQLite 3

Trovare righe

AttivitàCodice
Colonne di una tabella SELECT id, email FROM users;
Filtro SELECT * FROM orders WHERE status = 'paid' AND total > 100;
Uno tra più valori WHERE status IN ('paid', 'shipped')
Intervallo (estremi inclusi) WHERE created_at BETWEEN '2026-01-01' AND '2026-01-31'
Pattern WHERE email LIKE '%@example.com'
Valore mancante WHERE phone IS NULL
Ordina, dal più recente ORDER BY created_at DESC
Prime 10 righe LIMIT 10
Valori distinti SELECT DISTINCT status FROM orders;

SQL Server usa SELECT TOP 10 al posto di LIMIT. BETWEEN sui timestamp include solo la mezzanotte della data finale: per giornate intere usa < giorno successivo.

Aggregare

AttivitàCodice
Conta le righe SELECT COUNT(*) FROM orders;
Conta i valori non NULL SELECT COUNT(shipped_at) FROM orders;
Conta i valori distinti SELECT COUNT(DISTINCT user_id) FROM orders;
Totali per gruppo SELECT status, COUNT(*), SUM(total) FROM orders GROUP BY status;
Filtra i gruppi SELECT user_id, COUNT(*) FROM orders GROUP BY user_id HAVING COUNT(*) > 5;
Minimo, massimo, media SELECT MIN(total), MAX(total), AVG(total) FROM orders;

WHERE filtra le righe prima del raggruppamento; HAVING filtra i gruppi dopo.

Join

AttivitàCodice
Solo le righe corrispondenti SELECT o.id, u.email FROM orders o JOIN users u ON u.id = o.user_id;
Mantieni tutte le righe di sinistra SELECT u.email, o.id FROM users u LEFT JOIN orders o ON o.user_id = u.id;
Righe senza corrispondenza (anti-join) SELECT u.* FROM users u LEFT JOIN orders o ON o.user_id = u.id WHERE o.id IS NULL;
Lo stesso, con NOT EXISTS SELECT * FROM users u WHERE NOT EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id);

Un join su una chiave uno-a-molti ripete il lato "uno". Se SUM() sembra troppo grande dopo un join, il join ha moltiplicato le righe.

Controlli sui dati che fanno i tester

AttivitàCodice
Duplicati SELECT email, COUNT(*) FROM users GROUP BY email HAVING COUNT(*) > 1;
Orfani (figlio senza genitore) SELECT o.* FROM orders o LEFT JOIN users u ON u.id = o.user_id WHERE u.id IS NULL;
Campo obbligatorio vuoto SELECT * FROM users WHERE email IS NULL OR TRIM(email) = '';
Valori fuori intervallo SELECT * FROM order_items WHERE quantity <= 0 OR unit_price < 0;
Totale testata ≠ righe d’ordine SELECT o.id FROM orders o JOIN order_items i ON i.order_id = o.id GROUP BY o.id, o.total HAVING o.total <> SUM(i.quantity * i.unit_price);
La riga esiste dopo un’azione nella UI SELECT * FROM orders WHERE user_id = 42 ORDER BY created_at DESC LIMIT 1;

Trappole del NULL

TrappolaCosa succede
WHERE col = NULL Mai vero. Usa IS NULL / IS NOT NULL.
WHERE status <> 'paid' Esclude le righe in cui status è NULL. Aggiungi OR status IS NULL se le vuoi includere.
NOT IN (subquery che restituisce un NULL) Non restituisce alcuna riga. Usa invece NOT EXISTS.
COUNT(col) vs COUNT(*) COUNT(col) salta i NULL, COUNT(*) conta ogni riga.
Aritmetica con NULL price + NULL è NULL. Usa COALESCE(col, 0) se 0 è il default corretto.

Window function

AttivitàCodice
Numera le righe per gruppo ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created_at DESC)
Riga più recente per gruppo SELECT * FROM (SELECT o.*, ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created_at DESC) AS rn FROM orders o) t WHERE rn = 1;
Classifica con pari merito RANK() OVER (ORDER BY total DESC) / DENSE_RANK() …
Valore della riga precedente LAG(status) OVER (PARTITION BY test_name ORDER BY run_at)
Totale progressivo SUM(total) OVER (ORDER BY created_at)

Supportate in PostgreSQL, MySQL 8+, SQLite 3.25+ e SQL Server. Una window function non si può usare nella WHERE: filtra in una query esterna.

Modificare i dati in sicurezza

AttivitàCodice
Inserimento INSERT INTO users (email, name) VALUES ('qa+1@example.com', 'QA One');
Aggiornamento (sempre con WHERE) UPDATE orders SET status = 'cancelled' WHERE id = 1043;
Cancellazione (sempre con WHERE) DELETE FROM sessions WHERE user_id = 42;
Prova e poi annulla
BEGIN;
UPDATE orders SET status = 'cancelled' WHERE id = 1043;
SELECT status FROM orders WHERE id = 1043;
ROLLBACK;

Esegui prima la stessa WHERE come SELECT e controlla il numero di righe prima di fare UPDATE o DELETE.

Esercitati e approfondisci

Altri cheat sheet

Scrivi per cercare in tutto SDETRole.

Ricerca full-text con Pagefind · funziona nel tuo browser Apri la pagina di ricerca →