Développement

Aide-mémoire SQL

SELECT, jointures, GROUP BY/HAVING et index : les bases SQL qui couvrent l’immense majorité des requêtes du quotidien.

Gratuit Mis à jour le 11 septembre 2026

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.

#Web #Base de données
naviguer ouvrir Esc fermer