Aide-mémoire SQL
SELECT, jointures, GROUP BY/HAVING et index : les bases SQL qui couvrent l’immense majorité des requêtes du quotidien.
Lire des données
SELECT nom, email FROM utilisateurs WHERE actif = 1 ORDER BY nom ASC LIMIT 20; SELECT DISTINCT pays FROM clients; SELECT COUNT(*) AS total FROM commandes WHERE statut = 'payee';
Jointures
SELECT c.nom, o.total FROM commandes o JOIN clients c ON c.id = o.client_id; -- LEFT JOIN garde toutes les lignes de gauche même sans correspondance SELECT c.nom, o.total FROM clients c LEFT JOIN commandes o ON o.client_id = c.id;
| Jointure | Renvoie |
|---|---|
INNER JOIN |
Seulement les lignes qui correspondent des deux côtés |
LEFT JOIN |
Toutes les lignes de gauche + correspondances à droite (NULL sinon) |
RIGHT JOIN |
L'inverse du LEFT JOIN |
FULL OUTER JOIN |
Toutes les lignes des deux côtés |
Agrégation
SELECT client_id, SUM(total) AS ca, COUNT(*) AS nb_commandes FROM commandes GROUP BY client_id HAVING SUM(total) > 1000 ORDER BY ca DESC;
WHERE filtre les lignes avant le regroupement ; HAVING filtre les groupes après GROUP BY. Impossible d'utiliser une fonction d'agrégation (SUM, COUNT…) dans un WHERE.
Écrire des données
INSERT INTO utilisateurs (nom, email) VALUES ('Ana', 'ana@exemple.fr'); UPDATE commandes SET statut = 'expediee' WHERE id = 42; DELETE FROM paniers WHERE cree_le < NOW() - INTERVAL 30 DAY;
Index et performance
CREATE INDEX idx_commandes_client ON commandes (client_id); EXPLAIN SELECT * FROM commandes WHERE client_id = 42;
Sous-requêtes et CTE
-- sous-requête dans le WHERE SELECT nom FROM clients WHERE id IN (SELECT client_id FROM commandes WHERE total > 500); -- CTE (WITH), plus lisible pour des requêtes complexes WITH gros_clients AS ( SELECT client_id, SUM(total) AS ca FROM commandes GROUP BY client_id HAVING SUM(total) > 1000 ) SELECT c.nom, g.ca FROM gros_clients g JOIN clients c ON c.id = g.client_id ORDER BY g.ca DESC;
Fonctions de fenêtrage (window functions)
-- classer les commandes par client sans les regrouper (contrairement à GROUP BY) SELECT client_id, total, RANK() OVER (PARTITION BY client_id ORDER BY total DESC) AS rang, SUM(total) OVER (PARTITION BY client_id) AS total_client FROM commandes;
Contrairement à GROUP BY qui fusionne les lignes, une fonction de fenêtrage garde chaque ligne individuelle tout en calculant une valeur agrégée « à côté » — idéal pour un classement, un cumul ou une comparaison à la moyenne du groupe sans perdre le détail.
Questions fréquentes
Quelle différence entre DELETE et TRUNCATE ?
`DELETE` supprime ligne par ligne, peut avoir un `WHERE` et se journalise (annulable dans une transaction). `TRUNCATE` vide toute la table d'un coup, plus rapide, mais irréversible et sans `WHERE` possible.
Pourquoi ma requête est-elle lente malgré un index ?
Un index n'aide que si la colonne est utilisée seule dans le `WHERE`/`JOIN` (pas dans une fonction comme `LOWER(colonne)`) et que l'optimiseur le juge plus rapide qu'un scan complet. `EXPLAIN` montre le plan réellement choisi.
Quand utiliser une fonction de fenêtrage plutôt que GROUP BY ?
Dès que vous avez besoin du détail de chaque ligne EN PLUS d'une valeur agrégée (un rang, un cumul, une comparaison à la moyenne) — GROUP BY, lui, ne renvoie qu'une ligne par groupe et perd le détail.
Merci pour votre retour !