Aller au contenu
SDETRole
SDETRole

Apprendre / Aide-mémoire

Aide-mémoire SQL pour testeurs

Le SQL dont les testeurs se servent pour vérifier les données derrière une UI ou une API : retrouver l’enregistrement, vérifier qu’il a changé, et traquer les doublons, orphelins et NULL qui ne devraient pas être là. La syntaxe est du SQL standard qui fonctionne sur PostgreSQL, MySQL 8 et SQLite. Lorsqu’une base de données diffère, la note le précise.

Vérifié avec SQL standard ; vérifié sur PostgreSQL 16, MySQL 8 et SQLite 3

Trouver des lignes

TâcheCode
Colonnes d’une table SELECT id, email FROM users;
Filtrer SELECT * FROM orders WHERE status = 'paid' AND total > 100;
Une valeur parmi plusieurs WHERE status IN ('paid', 'shipped')
Intervalle (bornes incluses) WHERE created_at BETWEEN '2026-01-01' AND '2026-01-31'
Motif WHERE email LIKE '%@example.com'
Valeur manquante WHERE phone IS NULL
Trier, plus récent d’abord ORDER BY created_at DESC
10 premières lignes LIMIT 10
Valeurs distinctes SELECT DISTINCT status FROM orders;

SQL Server utilise SELECT TOP 10 au lieu de LIMIT. Sur des timestamps, BETWEEN n’inclut que minuit de la date de fin ; utilisez < lendemain pour couvrir des journées entières.

Agréger

TâcheCode
Compter les lignes SELECT COUNT(*) FROM orders;
Compter les valeurs non NULL SELECT COUNT(shipped_at) FROM orders;
Compter les valeurs distinctes SELECT COUNT(DISTINCT user_id) FROM orders;
Totaux par groupe SELECT status, COUNT(*), SUM(total) FROM orders GROUP BY status;
Filtrer les groupes SELECT user_id, COUNT(*) FROM orders GROUP BY user_id HAVING COUNT(*) > 5;
Min, max, moyenne SELECT MIN(total), MAX(total), AVG(total) FROM orders;

WHERE filtre les lignes avant le regroupement ; HAVING filtre les groupes après.

Jointures

TâcheCode
Lignes correspondantes uniquement SELECT o.id, u.email FROM orders o JOIN users u ON u.id = o.user_id;
Garder toutes les lignes de gauche SELECT u.email, o.id FROM users u LEFT JOIN orders o ON o.user_id = u.id;
Lignes sans correspondance (anti-jointure) SELECT u.* FROM users u LEFT JOIN orders o ON o.user_id = u.id WHERE o.id IS NULL;
Idem, avec NOT EXISTS SELECT * FROM users u WHERE NOT EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id);

Une jointure sur une clé un-à-plusieurs répète le côté « un ». Si un SUM() semble trop élevé après une jointure, c’est que la jointure a démultiplié les lignes.

Contrôles de données des testeurs

TâcheCode
Doublons SELECT email, COUNT(*) FROM users GROUP BY email HAVING COUNT(*) > 1;
Orphelins (enfant sans parent) SELECT o.* FROM orders o LEFT JOIN users u ON u.id = o.user_id WHERE u.id IS NULL;
Champ obligatoire vide SELECT * FROM users WHERE email IS NULL OR TRIM(email) = '';
Valeurs hors limites SELECT * FROM order_items WHERE quantity <= 0 OR unit_price < 0;
Total d’en-tête ≠ lignes de détail 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 ligne existe après une action dans l’UI SELECT * FROM orders WHERE user_id = 42 ORDER BY created_at DESC LIMIT 1;

Pièges du NULL

PiègeCe qui se passe
WHERE col = NULL Jamais vrai. Utilisez IS NULL / IS NOT NULL.
WHERE status <> 'paid' Ignore les lignes où status est NULL. Ajoutez OR status IS NULL si vous les voulez.
NOT IN (sous-requête qui renvoie un NULL) Ne renvoie aucune ligne. Utilisez plutôt NOT EXISTS.
COUNT(col) vs COUNT(*) COUNT(col) ignore les NULL, COUNT(*) compte toutes les lignes.
Arithmétique avec NULL price + NULL vaut NULL. Enveloppez avec COALESCE(col, 0) si 0 est la bonne valeur par défaut.

Fonctions de fenêtrage

TâcheCode
Numéroter les lignes par groupe ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created_at DESC)
Dernière ligne par groupe 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;
Classement avec ex æquo RANK() OVER (ORDER BY total DESC) / DENSE_RANK() …
Valeur de la ligne précédente LAG(status) OVER (PARTITION BY test_name ORDER BY run_at)
Total cumulé SUM(total) OVER (ORDER BY created_at)

Pris en charge par PostgreSQL, MySQL 8+, SQLite 3.25+ et SQL Server. Une fonction de fenêtrage ne peut pas être utilisée dans WHERE : filtrez dans une requête englobante.

Modifier les données sans risque

TâcheCode
Insérer INSERT INTO users (email, name) VALUES ('qa+1@example.com', 'QA One');
Mettre à jour (toujours avec WHERE) UPDATE orders SET status = 'cancelled' WHERE id = 1043;
Supprimer (toujours avec WHERE) DELETE FROM sessions WHERE user_id = 42;
Essayer, puis annuler
BEGIN;
UPDATE orders SET status = 'cancelled' WHERE id = 1043;
SELECT status FROM orders WHERE id = 1043;
ROLLBACK;

Exécutez d’abord le même WHERE dans un SELECT et vérifiez le nombre de lignes avant tout UPDATE ou DELETE.

S’exercer et approfondir

Autres aide-mémoire

Saisissez un terme pour rechercher sur SDETRole.

Recherche plein texte par Pagefind · s’exécute dans votre navigateur Ouvrir la page de recherche →