Pourquoi SQL reste incontournable en 2026

Dans un monde dominĂ© par le NoSQL, les bases vectorielles et les API de type GraphQL, on pourrait croire que SQL appartient au passĂ©. Pourtant, 95% des applications web utilisent encore une base relationnelle en backend, et les offres d’emploi pour dĂ©veloppeurs mentionnent SQL dans plus de 70% des cas. MaĂźtriser SQL, ce n’est pas juste savoir Ă©crire un SELECT * FROM — c’est comprendre comment interroger, transformer et optimiser les donnĂ©es de façon efficace. Cet article te donne les clĂ©s pour passer de « dĂ©butant SQL » Ă  « dĂ©veloppeur qui Ă©crit des requĂȘtes qui cartonnent ».

1. Les CTE (Common Table Expressions) : ton nouveau meilleur ami

Les CTE, c’est la fonctionnalitĂ© qui change tout. Au lieu d’Ă©crire des sous-requĂȘtes imbriquĂ©es illisibles, tu peux dĂ©composer une requĂȘte complexe en Ă©tapes nommĂ©es, comme des variables dans un script Python.

Exemple concret : tu veux trouver les clients qui ont dĂ©pensĂ© plus de 1000€ le mois dernier, triĂ©s par montant total.

WITH depenses_mensuelles AS (
    SELECT
        client_id,
        SUM(montant) AS total_depense
    FROM commandes
    WHERE date_commande >= DATE_TRUNC('month', CURRENT_DATE - INTERVAL '1 month')
      AND date_commande < DATE_TRUNC('month', CURRENT_DATE)
    GROUP BY client_id
)
SELECT c.nom, c.email, dm.total_depense
FROM clients c
JOIN depenses_mensuelles dm ON c.id = dm.client_id
WHERE dm.total_depense > 1000
ORDER BY dm.total_depense DESC;

Pourquoi c’est mieux :

  • LisibilitĂ© — chaque bloc a un nom qui explique son rĂŽle
  • RĂ©utilisabilitĂ© — tu peux rĂ©fĂ©rencer le mĂȘme CTE plusieurs fois dans la requĂȘte
  • DĂ©bogage — tu peux exĂ©cuter chaque CTE sĂ©parĂ©ment pour vĂ©rifier son rĂ©sultat
  • Performance — le moteur SQL optimise le plan d’exĂ©cution global, pas chaque sous-requĂȘte indĂ©pendamment

Les CTE récursives sont encore plus puissantes pour les hiérarchies (organigrammes, catégories arborescentes, graphes). PostgreSQL, MySQL 8+, SQLite, et SQL Server les supportent toutes.

2. Les fonctions de fenĂȘtrage (Window Functions) — le super-pouvoir SQL

Les fonctions de fenĂȘtrage permettent de calculer sur un ensemble de lignes liĂ©es sans perdre le dĂ©tail de chaque ligne. LĂ  oĂč un GROUP BY agrĂšge et rĂ©sume, une window function prĂ©serve les lignes individuelles tout en ajoutant des calculs contextuels.

Cas typique : classer les produits par catégorie selon leurs ventes.

SELECT
    nom,
    categorie,
    chiffre_affaires,
    RANK() OVER (PARTITION BY categorie ORDER BY chiffre_affaires DESC) AS rang_categorie
FROM produits;

Les fonctions de fenĂȘtrage les plus utiles :

  • ROW_NUMBER() — numĂ©rotation sĂ©quentielle (utile pour la pagination)
  • RANK() et DENSE_RANK() — classement avec gestion des ex-aequo
  • LAG() et LEAD() — accĂ©der Ă  la ligne prĂ©cĂ©dente ou suivante (idĂ©al pour les comparaisons mois par mois)
  • SUM() OVER (...) — totaux cumulatifs
  • AVG() OVER (...) — moyennes mobiles

Exemple avancé : calculer la différence de ventes entre chaque mois et le mois précédent.

SELECT
    DATE_TRUNC('month', date_vente) AS mois,
    SUM(montant) AS ventes,
    LAG(SUM(montant)) OVER (ORDER BY DATE_TRUNC('month', date_vente)) AS ventes_mois_precedent,
    SUM(montant) - LAG(SUM(montant)) OVER (ORDER BY DATE_TRUNC('month', date_vente)) AS evolution
FROM ventes
GROUP BY DATE_TRUNC('month', date_vente)
ORDER BY mois;

Ce genre de requĂȘte, qui nĂ©cessitait une jointure sur elle-mĂȘme ou un sous-programme, se fait en 10 lignes avec les window functions.

3. L’optimisation des performances — Ă©crire des requĂȘtes rapides

Une mauvaise requĂȘte SQL peut faire ramer une application entiĂšre. Voici les rĂ©flexes Ă  acquĂ©rir.

3.1. Toujours utiliser EXPLAIN

Avant d’optimiser, mesure. EXPLAIN ANALYZE (PostgreSQL) ou EXPLAIN (MySQL) te montre le plan d’exĂ©cution et les goulets d’Ă©tranglement.

EXPLAIN ANALYZE
SELECT * FROM commandes WHERE client_id = 42;

Le résultat te dit : scan séquentiel (lent) ou index scan (rapide) ? Combien de lignes examinées ? Combien de temps réel ?

3.2. Les index — le secret des requĂȘtes rapides

Sans index, une table de 1 million de lignes est scannĂ©e intĂ©gralement Ă  chaque requĂȘte. Avec un index, c’est une recherche en O(log n).

RĂšgles d’or :

  • Indexer les colonnes utilisĂ©es dans les WHERE, JOIN et ORDER BY
  • Les index composites (plusieurs colonnes) sont puissants mais l’ordre des colonnes compte
  • Ne pas indexer une colonne avec trĂšs peu de valeurs distinctes (ex: un boolĂ©en) — l’index ne sert Ă  rien
  • Éviter les index sur les colonnes frĂ©quemment mises Ă  jour (surcoĂ»t en Ă©criture)

PiĂšge frĂ©quent : WHERE YEAR(date_commande) = 2026 empĂȘche l’utilisation d’un index sur date_commande. Écrire WHERE date_commande >= '2026-01-01' AND date_commande < '2027-01-01' permet l’index.

3.3. Éviter les anti-patterns

  • SELECT * en production — toujours lister les colonnes nĂ©cessaires
  • N+1 queries — charger 100 commandes puis faire 100 requĂȘtes pour les clients au lieu d’une seule jointure
  • Fonctions sur les colonnes indexĂ©es — WHERE LOWER(email) = 'x@y.com' dĂ©sactive l’index (solution : index fonctionnel ou colonne normalisĂ©e)
  • Jointures implicites — FROM a, b WHERE a.id = b.id vs FROM a JOIN b ON a.id = b.id (mĂȘme rĂ©sultat mais lisibilitĂ© et contrĂŽle)

4. SQL et Python : le duo gagnant des applications modernes

En tant que développeur Python, tu vas probablement interagir avec SQL via un ORM (SQLAlchemy, Django ORM) ou directement avec psycopg2 ou aiomysql.

ORM vs SQL brut : quand utiliser quoi ?

  • ORM — opĂ©rations CRUD simples, crĂ©ation de schĂ©ma, prototypage rapide
  • SQL brut — rapports complexes, requĂȘtes multi-agrĂ©gats, optimisation fine, batch updates

Bon compromis : SQLAlchemy avec des raw queries pour les cas complexes :

from sqlalchemy import text

rapport = session.execute(text("""
    WITH ventes_mensuelles AS (
        SELECT
            DATE_TRUNC('month', date_vente) AS mois,
            produit_id,
            SUM(quantite) AS total_qte,
            SUM(montant) AS total_ca
        FROM ventes
        WHERE date_vente >= :debut
        GROUP BY mois, produit_id
    )
    SELECT v.mois, p.nom, v.total_ca,
           RANK() OVER (PARTITION BY v.mois ORDER BY v.total_ca DESC) AS rang
    FROM ventes_mensuelles v
    JOIN produits p ON v.produit_id = p.id
    ORDER BY v.mois DESC, rang
"""), {"debut": "2026-01-01"}).fetchall()

Avec les CTE et les paramÚtres nommés (:debut), tu obtiens le meilleur des deux mondes : la puissance de SQL et la sécurité de Python.

5. Les fonctionnalités modernes à connaßtre selon ton SGBD

Tous les SQL ne se valent pas. Voici ce qui différencie les principaux systÚmes :

FonctionnalitéPostgreSQLMySQL 8+SQLite
CTE rĂ©cursives✅✅✅
Window functions✅ Complùtes✅ (depuis 8.0)✅ (depuis 3.25)
Index partiels✅ WHERE❌✅ WHERE
JSON natif✅ JSONB✅ JSON✅ (depuis 3.38)
Types array✅❌❌
Recherche plein texte✅ Natif✅ FULLTEXT✅ FTS5
UPSERT✅ ON CONFLICT✅ ON DUPLICATE✅ ON CONFLICT

Si tu dĂ©butes ou si tu veux un environnement de test portable, SQLite est parfait. Pour du vrai projet en production, PostgreSQL est le choix le plus complet et le plus utilisĂ© dans l’Ă©cosystĂšme Python.

Conclusion

SQL n’est pas une compĂ©tence « hĂ©ritage » — c’est un levier de productivitĂ© immĂ©diat pour tout dĂ©veloppeur. Les CTE rendent tes requĂȘtes lisibles, les window functions les rendent puissantes, et les bonnes pratiques d’optimisation les rendent rapides.

Que tu construises une API REST, un dashboard analytics ou une application SaaS, ces techniques te permettront d’aller plus loin avec moins de code. Et contrairement Ă  ce qu’on lit parfois, SQL et NoSQL ne sont pas en concurrence : ce sont des outils complĂ©mentaires. Mais SQL reste, de loin, le plus universel.

PrĂȘt Ă  approfondir ? La maĂźtrise de SQL est un des fondamentaux qu’on travaille en dĂ©tail dans nos formations. Si tu veux passer de « je me dĂ©brouille » Ă  « je conçois des bases de donnĂ©es performantes », dĂ©couvre nos programmes.