SQL Pratique
Reviewer SQL généré par IA : guide pratique
18 min de lecture

Reviewer SQL généré par IA : guide pratique

Maîtrisez la vérification du SQL généré par ChatGPT, Copilot. Les 8 erreurs les plus fréquentes, checklist de revue systématique et cas concrets par métier.

Avatar de Thomas LeroyThomas Leroy

📌 Ce qu'il faut retenir

  • Le SQL généré par IA compile presque toujours — les erreurs sont logiques, pas syntaxiques
  • Les JOINs incorrects (multiplication de lignes, LEFT JOIN annulé par WHERE) sont les erreurs les plus fréquentes et les plus dangereuses
  • Les NULL ignorés faussent silencieusement les agrégations et les taux calculés
  • Utilisez une checklist de revue systématiquement avant d'exécuter du SQL généré par IA
  • Ne mettez jamais en production du SQL non vérifié, quelle que soit la source

En 2026, la majorité des data analysts utilisent l'IA (ChatGPT, Copilot, Gemini) pour écrire ou accélérer leurs requêtes SQL. C'est un gain de productivité réel. Mais l'IA fait des erreurs — et pas des erreurs de syntaxe évidentes qui empêchent l'exécution. Non, elle fait des erreurs logiques subtiles qui produisent des résultats plausibles mais faux.

Ce guide vous expose les 8 erreurs les plus fréquentes du SQL généré par IA, comment les détecter, et comment les corriger systématiquement.

Pourquoi le SQL généré par IA est dangereux

Le SQL généré par IA compile et s'exécute presque toujours. Il produit un résultat. Et ce résultat a l'air correct. C'est ce qui le rend dangereux : vous pouvez baser des décisions business sur des données fausses sans le savoir.

Les LLM ne « comprennent » pas vos données. Ils ne connaissent pas :

  • Les cardinalités de vos tables (1:1, 1:N, N:M)
  • Les valeurs NULL présentes dans vos colonnes
  • Les cas limites de votre business
  • Les conventions de nommage spécifiques à votre entreprise

⚠️ Attention

D'après une étude de Stack Overflow 2024, 23% des développeurs ont déployé du code généré par IA sans revue complète. En SQL, cette pratique peut corrompre silencieusement vos métriques business pendant des mois. Une erreur de JOIN peut multiplier les totaux par un facteur de 10 sans que personne le remarque.

Tableau : Impact des erreurs SQL non détectées

Type d'erreurDétectabilitéImpact businessDélai avant détection
JOIN incorrect (multiplication de lignes)Très difficileMétriques multipliées par 10-100×1-6 mois
NULL ignorés dans agrégationDifficileTaux de conversion faux de 15-30%2-4 semaines
LEFT JOIN devenu INNER JOINTrès difficileClients actifs sous-comptabilisés de 20-50%1-3 mois
Window function frame incorrecteDifficileTendances inversées ou lissées3-8 semaines
Mauvais dialecte SQLFacileRequête ne s'exécute pasImmédiat
Division par zéro silencieuseTrès difficileKPI = NULL sans alerte2-4 mois
Erreur de logique métierTrès difficileDécisions business fausses1-12 mois
Performance catastrophiqueTrès facileTimeout, indisponibilitéImmédiat

Les 8 erreurs les plus fréquentes

Erreur 1 : Multiplication de lignes par les JOINs

C'est l'erreur la plus fréquente et la plus dangereuse.

-- Prompt : "Total des ventes et nombre de retours par client"
-- SQL généré par l'IA :
SELECT
    c.name,
    SUM(o.amount) AS total_sales,
    COUNT(r.id) AS nb_returns
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id
LEFT JOIN returns r ON c.id = r.customer_id
GROUP BY c.name;

**Le problème** : si un client a 5 commandes et 3 retours, le JOIN produit 15 lignes (5 × 3 = produit cartésien partiel). Le total des ventes est multiplié par 3, le nombre de retours par 5.

**La correction** — pré-agréger dans des CTEs séparées :

```sql
WITH sales_by_customer AS (
    SELECT customer_id, SUM(amount) AS total_sales
    FROM orders
    GROUP BY customer_id
),
returns_by_customer AS (
    SELECT customer_id, COUNT(*) AS nb_returns
    FROM returns
    GROUP BY customer_id
)
SELECT
    c.name,
    COALESCE(s.total_sales, 0) AS total_sales,
    COALESCE(r.nb_returns, 0) AS nb_returns
FROM customers c
LEFT JOIN sales_by_customer s ON c.id = s.customer_id
LEFT JOIN returns_by_customer r ON c.id = r.customer_id;
<div class="callout callout-tip">
<p class="callout-title">💡 Bon à savoir</p>
<p><strong>Détecter :</strong> comparez COUNT(*) avant et après le JOIN. Si le nombre de lignes augmente de manière inattendue, il y a une multiplication. <strong>Corriger :</strong> pré-agrégez chaque table dans une CTE séparée avant de joindre. Joignez uniquement des résultats déjà agrégés au niveau de la clé de jointure.</p>
</div>

### Erreur 2 : LEFT JOIN transformé en INNER JOIN

L'IA ajoute souvent un `WHERE` sur la table de droite, ce qui annule le LEFT JOIN.

```sql
-- L'IA génère :
SELECT c.name, o.order_date
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id
WHERE o.status = 'shipped';  -- élimine les clients sans commande

La correction — déplacer la condition dans le ON :

SELECT c.name, o.order_date
FROM customers c
LEFT JOIN orders o 
    ON c.id = o.customer_id 
    AND o.status = 'shipped';

💡 Bon à savoir

Détecter : cherchez tout WHERE qui filtre sur une colonne de la table de droite d'un LEFT JOIN. Si la condition est dans WHERE (pas dans ON), elle transforme silencieusement le LEFT JOIN en INNER JOIN. Corriger : déplacez la condition de filtrage de la table de droite dans la clause ON du JOIN.

Pour maîtriser les JOINs dans tous leurs cas, consultez notre guide complet des JOINs SQL.

Erreur 3 : Fenêtre par défaut incorrecte

L'IA utilise fréquemment les window functions sans spécifier la frame :

-- L'IA génère :
SELECT
    date,
    amount,
    AVG(amount) OVER (ORDER BY date) AS moving_avg
FROM sales;

Le problème : sans ROWS BETWEEN, la frame par défaut est RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW. Avec RANGE, toutes les lignes ayant la même date sont incluses dans le même groupe — ce n'est pas une moyenne mobile.

La correction :

SELECT
    date,
    amount,
    AVG(amount) OVER (
        ORDER BY date
        ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
    ) AS moving_avg_7d
FROM sales;

Pour comprendre les subtilités des fonctions fenêtre, voir notre guide des fonctions fenêtre SQL.

Erreur 4 : NULL ignorés dans les calculs

L'IA oublie souvent de traiter les NULL :

-- L'IA génère : taux de complétion d'un formulaire
SELECT
    100.0 * COUNT(CASE WHEN step = 'complete' THEN 1 END) / COUNT(*) AS completion_rate
FROM form_events;

Le problème : si step peut être NULL, ces lignes ne sont ni comptées dans le numérateur ni correctement gérées. Il faut aussi se demander si COUNT(*) est le bon dénominateur (tous les événements ? ou les utilisateurs uniques ?).

La correction :

SELECT
    ROUND(
        100.0 * COUNT(DISTINCT CASE WHEN step = 'complete' THEN user_id END)
        / NULLIF(COUNT(DISTINCT user_id), 0),
        1
    ) AS completion_rate
FROM form_events;

💡 Bon à savoir

Détecter : cherchez les divisions (risque de division par zéro), les COUNT(*) utilisés comme dénominateur, et les conditions sur des colonnes nullables sans COALESCE ou IS NULL. Corriger : utilisez NULLIF(dénominateur, 0) pour éviter les divisions par zéro, COUNT(DISTINCT colonne) pour les valeurs uniques réelles, et COALESCE(col, valeur_défaut) pour remplacer les NULL dans les agrégations.

Erreur 5 : Mauvais dialecte SQL

L'IA génère parfois du SQL pour le mauvais dialecte :

-- Syntaxe PostgreSQL, mais vous êtes sur MySQL
SELECT DATE_TRUNC('month', order_date) AS month FROM orders;

-- En MySQL, il faut :
SELECT DATE_FORMAT(order_date, '%Y-%m-01') AS month FROM orders;

Ou encore :

-- L'IA utilise ILIKE (PostgreSQL) au lieu de LIKE avec LOWER (MySQL)
SELECT * FROM products WHERE name ILIKE '%widget%';

-- En MySQL :
SELECT * FROM products WHERE LOWER(name) LIKE '%widget%';

Erreur 6 : Agrégation sans les bonnes colonnes dans GROUP BY

-- L'IA génère :
SELECT
    department,
    employee_name,
    MAX(salary) AS max_salary
FROM employees
GROUP BY department;

Le problème : employee_name n'est pas dans le GROUP BY. PostgreSQL et SQL Server rejettent cette requête. MySQL en mode non-strict retourne une valeur arbitraire pour employee_name — qui n'est pas forcément l'employé avec le salaire max.

La correction — utiliser une window function :

WITH ranked AS (
    SELECT *, RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS rn
    FROM employees
)
SELECT department, employee_name, salary
FROM ranked WHERE rn = 1;

Pour approfondir les GROUP BY et HAVING, consultez notre guide GROUP BY et HAVING.

Erreur 7 : Performances catastrophiques

L'IA écrit du SQL qui fonctionne sur 1000 lignes mais explose sur 10 millions :

-- L'IA génère : sous-requête corrélée sur chaque ligne
SELECT
    e.name,
    e.salary,
    (SELECT AVG(salary) FROM employees e2
     WHERE e2.department_id = e.department_id) AS dept_avg
FROM employees e;

La correction — une seule passe avec une window function :

SELECT
    name,
    salary,
    AVG(salary) OVER (PARTITION BY department_id) AS dept_avg
FROM employees;

Pour plus de techniques d'optimisation, voir 10 techniques d'optimisation SQL.

Erreur 8 : Logique métier incorrecte

L'IA ne connaît pas votre business. Elle peut :

  • Compter les annulations comme des ventes
  • Inclure les employés inactifs dans les statistiques
  • Confondre la date de création et la date de livraison
  • Utiliser le prix catalogue au lieu du prix réel
-- L'IA génère : CA basé sur le prix catalogue
SELECT SUM(p.catalog_price * oi.quantity) AS revenue
FROM order_items oi
JOIN products p ON oi.product_id = p.id;

-- Mais le vrai CA est basé sur le prix effectivement payé
SELECT SUM(oi.unit_price * oi.quantity) AS revenue
FROM order_items oi
WHERE order_status = 'delivered';

Erreurs par profil d'utilisateur et cas concrets

Erreurs des débutants (< 1 an d'expérience)

Les débutants font souvent confiance aveuglément à l'IA et ne détectent pas les erreurs subtiles.

Exemple : Clara, analyste marketing junior

Clara demande : "Taux de conversion par canal d'acquisition"

-- L'IA génère (erreur subtile) :
SELECT 
    channel,
    COUNT(CASE WHEN status = 'converted' THEN 1 END) * 100.0 / COUNT(*) as conversion_rate
FROM users
GROUP BY channel;

Le problème : COUNT(*) inclut tous les utilisateurs, même ceux qui viennent juste de s'inscrire et n'ont pas encore eu le temps de convertir. Le taux est artificiellement bas.

La correction métier :

SELECT 
    channel,
    COUNT(CASE WHEN status = 'converted' THEN 1 END) * 100.0 / 
    COUNT(CASE WHEN created_at <= CURRENT_DATE - INTERVAL '7 days' THEN 1 END) as conversion_rate,
    COUNT(*) as total_users,
    COUNT(CASE WHEN status = 'converted' THEN 1 END) as converted_users
FROM users
WHERE created_at <= CURRENT_DATE - INTERVAL '7 days'
GROUP BY channel
ORDER BY conversion_rate DESC;

Erreurs des intermédiaires (2-4 ans)

Les utilisateurs intermédiaires détectent les erreurs évidentes mais ratent les subtilités métier.

Exemple : Marc, analyste financier

Marc demande : "Évolution du chiffre d'affaires mensuel avec croissance YoY"

-- L'IA génère (logique incomplète) :
WITH monthly_revenue AS (
    SELECT 
        DATE_TRUNC('month', order_date) as month,
        SUM(amount) as revenue
    FROM orders 
    WHERE status = 'paid'
    GROUP BY 1
)
SELECT 
    month,
    revenue,
    LAG(revenue, 12) OVER (ORDER BY month) as revenue_previous_year,
    ROUND((revenue - LAG(revenue, 12) OVER (ORDER BY month)) * 100.0 / 
    LAG(revenue, 12) OVER (ORDER BY month), 2) as yoy_growth_pct
FROM monthly_revenue;

Le problème : la requête ne gère pas les remboursements, les annulations tardives, ni les ajustements comptables. En finance, le CA doit être net.

La correction comptable :

WITH transactions AS (
    SELECT DATE_TRUNC('month', order_date) as month, amount
    FROM orders 
    WHERE status IN ('paid', 'delivered')
    UNION ALL
    SELECT DATE_TRUNC('month', refund_date) as month, -refund_amount
    FROM refunds 
    WHERE status = 'processed'
),
monthly_revenue AS (
    SELECT month, SUM(amount) as net_revenue
    FROM transactions
    GROUP BY month
)
SELECT 
    month,
    net_revenue,
    LAG(net_revenue, 12) OVER (ORDER BY month) as revenue_previous_year,
    ROUND((net_revenue - LAG(net_revenue, 12) OVER (ORDER BY month)) * 100.0 / 
         NULLIF(LAG(net_revenue, 12) OVER (ORDER BY month), 0), 2) as yoy_growth_pct
FROM monthly_revenue
ORDER BY month DESC;

Erreurs spécifiques à l'e-commerce

Exemple : Léa, e-commerce manager

"Taux de retour par catégorie de produit"

-- L'IA génère (erreur de périmètre) :
SELECT 
    p.category,
    COUNT(r.id) * 100.0 / COUNT(o.id) as return_rate
FROM orders o
JOIN order_items oi ON o.id = oi.order_id
JOIN products p ON oi.product_id = p.id
LEFT JOIN returns r ON oi.id = r.order_item_id
GROUP BY p.category;

Le problème : compte les commandes récentes qui n'ont pas encore eu le temps d'être retournées.

La correction :

WITH eligible_orders AS (
    -- Seulement les commandes livrées depuis plus de 7 jours
    SELECT oi.id as order_item_id, p.category
    FROM orders o
    JOIN order_items oi ON o.id = oi.order_id
    JOIN products p ON oi.product_id = p.id
    WHERE o.status = 'delivered' 
      AND o.delivery_date <= CURRENT_DATE - INTERVAL '7 days'
      AND o.delivery_date >= CURRENT_DATE - INTERVAL '6 months'
)
SELECT 
    e.category,
    COUNT(e.order_item_id) as total_eligible_items,
    COUNT(r.id) as returned_items,
    ROUND(COUNT(r.id) * 100.0 / NULLIF(COUNT(e.order_item_id), 0), 2) as return_rate_pct
FROM eligible_orders e
LEFT JOIN returns r ON e.order_item_id = r.order_item_id 
    AND r.status = 'approved'
GROUP BY e.category
HAVING COUNT(e.order_item_id) >= 100
ORDER BY return_rate_pct DESC;

Cas réels par type de base de données

PostgreSQL : pièges fréquents

Problème avec les fuseaux horaires :

-- L'IA génère (ignore le fuseau horaire) :
SELECT DATE_TRUNC('day', created_at) FROM orders;

-- Correction (prise en compte du fuseau métier) :
SELECT DATE_TRUNC('day', created_at AT TIME ZONE 'UTC' 
       AT TIME ZONE 'Europe/Paris') FROM orders;

BigQuery : erreurs typiques

Problème avec les ARRAY et les partitions :

-- L'IA génère (syntaxe incorrecte) :
SELECT user_id, tags[0] FROM users;

-- Correction BigQuery :
SELECT user_id, tags[OFFSET(0)] FROM users;

MySQL : pièges courants

Problème avec le GROUP BY strict :

-- MySQL 5.7+ en mode strict rejette :
SELECT department, name, COUNT(*) FROM employees GROUP BY department;

-- Correction :
SELECT department, ANY_VALUE(name), COUNT(*) FROM employees 
GROUP BY department;

Checklist de revue complète

Pour tous les profils

  • Exécution : la requête s'exécute-t-elle sans erreur ?
  • Résultat : le nombre de lignes est-il plausible ?
  • NULL : y a-t-il des NULL inattendus ou ignorés ?

Vérification des JOINs (priorité absolue)

  • Comptabilisez les lignes avant et après chaque JOIN
  • Si LEFT JOIN : des lignes de la table de gauche ont-elles disparu ?
  • Les conditions de filtrage de la table de droite sont-elles dans ON ?

Vérification des agrégations

  • COUNT vs COUNT DISTINCT : le bon est-il utilisé ?
  • GROUP BY contient toutes les colonnes non-agrégées
  • Les NULL sont traités dans les calculs de pourcentages
  • Pas de division par zéro possible (NULLIF)

Vérification business

  • Les bons statuts sont filtrés (actif/inactif, validé/brouillon)
  • Les bonnes dates sont utilisées (création/modification/livraison)
  • Recoupement avec une source alternative (Excel, dashboard)

Tableau récapitulatif : erreurs vs solutions

ErreurSymptômeSolution
Multiplication de lignes (JOIN)COUNT(*) augmente après JOINPré-agréger dans CTEs séparées
LEFT JOIN devenu INNERLignes de gauche disparaissentDéplacer WHERE dans ON
Window function frameRésultats ne correspondent pasSpécifier ROWS BETWEEN explicite
NULL ignorésTotaux manquent de lignesCOALESCE + NULLIF pour division
Mauvais dialecteErreur de syntaxeAdapter aux fonctions de la DB
GROUP BY incompletErreur de colonneWindow functions ou sous-requêtes
Performance mauvaiseTimeout, scan table completRemplacer sous-requêtes corrélées par window functions
Logique métier fausseRésultats ne correspondent pas au KPIValider avec domaine métier, tester cas limites

Intégration de l'IA dans votre flux de travail

Pour approfondir vos compétences en SQL appliqué, découvrez comment préparer un entretien SQL efficacement et comment utiliser l'IA comme outil de préparation.

Bonnes pratiques

  1. Toujours tester sur un échantillon : demandez LIMIT 100 et vérifiez manuellement 5-10 lignes
  2. Documenter les hypothèses : écrivez un commentaire explicitant la logique métier
  3. Versioner les requêtes : gardez l'historique des modifications (GitHub, Gitlab)
  4. Automatiser les tests : créez des tests SQL pour vos KPI critiques
-- Exemple : test que le CA mensuel n'a pas changé de > 20%
SELECT 
    month,
    net_revenue,
    LAG(net_revenue) OVER (ORDER BY month) as prev_month,
    CASE 
        WHEN ABS(net_revenue - LAG(net_revenue) OVER (ORDER BY month)) / 
             LAG(net_revenue) OVER (ORDER BY month) > 0.2 THEN 'ALERTE'
        ELSE 'OK'
    END as status
FROM monthly_revenue
ORDER BY month DESC LIMIT 3;

Erreurs par cas d'usage avancé

Analyse de cohorte (rétention)

L'IA oublie souvent que la rétention doit être mesurée sur un cohort équitable :

-- Faux : mélange des cohortes d'âges différents
SELECT 
    registration_month,
    DATE_TRUNC('month', login_date) as activity_month,
    COUNT(DISTINCT user_id) as active_users
FROM users u
LEFT JOIN logins l ON u.id = l.user_id
GROUP BY 1, 2;

-- Correct : fenêtre d'observation identique pour tous les cohorts
WITH cohorts AS (
    SELECT 
        user_id,
        DATE_TRUNC('month', registration_date) as cohort_month
    FROM users
    WHERE registration_date >= '2024-01-01' - INTERVAL '12 months'
),
activity_month_number AS (
    SELECT 
        c.cohort_month,
        c.user_id,
        (DATE_TRUNC('month', l.login_date)::date - c.cohort_month::date) / 30 as months_since_signup
    FROM cohorts c
    LEFT JOIN logins l ON c.user_id = l.user_id
        AND l.login_date >= c.cohort_month
)
SELECT 
    cohort_month,
    months_since_signup,
    COUNT(DISTINCT user_id) as retained_users
FROM activity_month_number
WHERE months_since_signup >= 0 AND months_since_signup <= 11
GROUP BY 1, 2;

Approfondissez avec notre article sur les exercices de rétention utilisateurs.

Analyses de tunnel conversion

L'IA confond souvent "avoir visité l'étape X" et "avoir complété l'étape X" :

-- Faux : compte aussi les abandons
SELECT 
    step,
    COUNT(DISTINCT user_id) as users
FROM funnel_events
GROUP BY step
ORDER BY step;

-- Correct : progression à travers le tunnel
WITH step_completion AS (
    SELECT 
        user_id,
        MAX(CASE WHEN step = 'step_1' THEN timestamp END) as step_1_time,
        MAX(CASE WHEN step = 'step_2' THEN timestamp END) as step_2_time,
        MAX(CASE WHEN step = 'step_3' THEN timestamp END) as step_3_time
    FROM funnel_events
    GROUP BY user_id
)
SELECT 
    'Step 1' as step,
    COUNT(DISTINCT CASE WHEN step_1_time IS NOT NULL THEN user_id END) as users
FROM step_completion
UNION ALL
SELECT 
    'Step 2',
    COUNT(DISTINCT CASE WHEN step_2_time IS NOT NULL AND step_1_time IS NOT NULL THEN user_id END)
FROM step_completion
UNION ALL
SELECT 
    'Step 3',
    COUNT(DISTINCT CASE WHEN step_3_time IS NOT NULL 
        AND step_2_time IS NOT NULL AND step_1_time IS NOT NULL THEN user_id END)
FROM step_completion;

Pour approfondir les analyses de conversion, consultez notre exercice tunnel conversion e-commerce.

Questions fréquentes

Comment tester rapidement si un JOIN multiplie les lignes ?

Ajoutez cette vérification avant et après le JOIN :

SELECT COUNT(*) as row_count FROM table1;  -- avant
SELECT COUNT(*) FROM table1 LEFT JOIN table2 ...;  -- après

Si le nombre explose, il y a un produit cartésien partiel. Vérifiez les cardinalités.

Le SQL compile mais les résultats semblent bizarres. Par où commencer ?

  1. Comparez avec une période antérieure (même requête il y a 1 mois)
  2. Vérifiez manuellement 10 lignes (vraiment, à la main)
  3. Croisez avec une autre source (Excel, autre dashboard)
  4. Testez les cas limites (NULL, valeur 0, dates limites)

Dois-je faire confiance à ChatGPT pour générer du SQL en production ?

Non, jamais directement. ChatGPT est excellent pour :

  • Générer un point de départ rapide
  • Expliquer une syntaxe
  • Corriger une erreur avec contexte

Mais il FAUT toujours :

  • Vérifier la logique métier
  • Tester sur un échantillon
  • Faire valider par quelqu'un d'expérience

Quelle est la meilleure pratique pour reviewer du SQL généré ?

  1. Lire le prompt (qu'a demandé l'utilisateur ?)
  2. Vérifier les JOINs (pas de multiplication ?)
  3. Vérifier les agrégations (GROUP BY complet ?)
  4. Tester sur échantillon (résultats cohérents ?)
  5. Valider métier (cas limites gérés ?)

L'IA génère souvent des CTEs inutiles. C'est grave ?

Non, c'est même une bonne pratique. Les CTEs :

  • Rendent le code lisible
  • Facilitent le debugging
  • Peuvent être testées indépendamment
  • N'ont pas d'impact de performance dans les engines modernes

Comment éviter que le LEFT JOIN devienne INNER JOIN ?

C'est LA erreur la plus fréquente. Règle simple :

Tout filtre sur la table de droite doit être dans ON, pas dans WHERE.

-- ❌ Mauvais
LEFT JOIN users u ON orders.user_id = u.id
WHERE u.status = 'active'

-- ✅ Bon
LEFT JOIN users u ON orders.user_id = u.id AND u.status = 'active'

Quand devrais-je préférer une sous-requête à une CTE ?

Les CTEs sont presque toujours meilleures pour :

  • La lisibilité (noms explicites)
  • Le debugging (testable indépendamment)
  • La réutilisabilité (inclure plusieurs fois sans dupliquer)

Les sous-requêtes dans SELECT peuvent être nécessaires pour :

  • Les calculs à niveau de ligne (très rare)
  • Les bases légères sans support CTE (très rare en 2026)

Le SQL s'exécute mais mon manager dit que ça ne match pas ses données Excel. Quoi faire ?

  1. Exportez 100 lignes du SQL, 100 du Excel
  2. Triez les deux par clé de jointure (client_id, date, etc.)
  3. Comparez manuellement (Excel : VLOOKUP ou Index/Match)
  4. Notez les divergences
  5. Cherchez dans le SQL : qu'est-ce qu'on compte différemment ?

Le problème est souvent : périmètre, dates, ou statuts.

Prêt à vous entraîner ?

50 exercices SQL interactifs avec éditeur en ligne, chronomètre et feedback IA.

Voir les exercices