Quels concepts SQL échouent la plupart des candidats en entretien ?

La majorité des candidats trébuchent sur six concepts SQL fondamentaux lors des entretiens data. Comprendre et maîtriser ces notions, illustrées par des exemples concrets, est clé pour réussir et convaincre les recruteurs exigeants.

3 principaux points à retenir.

  • Les fonctions fenêtres nécessitent un usage précis de l’ordre et du partitionnement pour éviter des résultats erronés.
  • Différencier WHERE et HAVING est essentiel pour appliquer correctement les filtres avant ou après agrégation.
  • Gérer les NULL avec COALESCE évite omissions et erreurs d’interprétation dans les résultats.

Pourquoi les fonctions fenêtres posent-elles problème en entretien SQL

Les fonctions fenêtres, c’est un peu comme la cerise sur le gâteau en SQL : toutes les poisons y tiennent mais leur usage est, ma foi, parfois peu compris des candidats en entretien. Prenons l’exemple de LAG() et RANK(). On pourrait penser qu’ils fonctionnent en mode « à la cool », mais sans le ORDER BY, préparez-vous à une belle pagaille. Pourquoi ? Parce qu’eux, ils ont besoin d’un peu de structure pour servir des résultats probants et prévisibles.

Lorsqu’on parle de non-determinisme, on évoque un comportement imprévisible. En d’autres termes, sans l’ORDER BY, chaque exécution peut potentiellement générer une sortie différente. Imaginez votre serveur SQL en train de jongler sans filet : ça ne donne pas vraiment confiance. En effet, chaque rangée peut être retournée dans un ordre différent si aucune instruction ne spécifie où placer la barre.

Voyons un exemple frappant pour illustrer cela :

🚀 Devenez un expert en Data Marketing avec nos formations !

Maîtrisez les outils essentiels pour analyser, automatiser et visualiser vos données comme un pro. De BigQuery SQL à Google Apps Script, en passant par Google Sheets et Looker Studio, nos formations couvrent tous les niveaux pour vous permettre d’optimiser vos flux de données, structurer vos bases SQL, automatiser vos tâches et créer des dashboards percutants. Que vous soyez débutant ou avancé, chaque formation est conçue pour une mise en pratique immédiate et un impact direct sur vos projets. Ne subissez plus vos données, prenez le contrôle dès aujourd’hui ! 📊🔥

SELECT 
    employee_id, 
    salary, 
    LAG(salary) OVER (PARTITION BY department_id ORDER BY employee_id) AS previous_salary
FROM 
    employees;

Ici, on utilise PARTITION BY pour diviser les salaires par département. Mais attention ! Si vous omettez l’ORDER BY, le résultat peut varier d’une exécution à l’autre. En revanche, corrigeons notre tir :

SELECT 
    employee_id, 
    salary, 
    LAG(salary) OVER (PARTITION BY department_id ORDER BY salary DESC) AS previous_salary
FROM 
    employees;

D’un coup, tout devient clair. En orderant par le salary de manière décroissante, chaque employé est évalué par rapport à son prédécesseur direct selon les critères choisis. Propre, net et précis. Rappelez-vous toujours : l’art de la requête SQL réside souvent dans la précision des détails. Une fois que le duo ORDER BY et PARTITION BY est bien maîtrisé, vous aurez directement un aussi bon score en entretien. Pour le reste, un petit tour sur des ressources comme DataCamp peut être un excellent point de départ. Qui sait ? Vous pourriez décrocher le job de vos rêves grâce à ces subtilités SQL !

Comment utiliser correctement WHERE et HAVING avec les agrégats

Quand on parle d’SQL et qu’on entre dans le vif du sujet, il y a un duo qui se retrouve souvent sur le banc des accusés : WHERE et HAVING. Les candidats en entretien se plantent parfois royalement sur leur utilisation, et croyez-moi, ça laisse une dernière impression. Pourquoi ? Parce qu’il y a un ordre d’exécution des clauses SQL qu’il faut absolument capter. En gros, WHERE fait le boulot en amont, tandis que HAVING agit après l’agrégation. Un peu comme si WHERE était le garde-frontière et HAVING le juge. Le premier filtre les données avant qu’elles soient agrégées, tandis que le second s’assure que les résultats de cette agrégation respectent certaines conditions.

Mais où ça coince le plus souvent ? Prenons un exemple typique : imaginez que vous essayez de récupérer les villes avec le minimum de ventes. Voici une requête mal foutue :


SELECT city, MIN(sales)
FROM sales_data
WHERE MIN(sales) > 1000
GROUP BY city;

Vous vous rendez compte du fiasco ? Mais bien sûr, le MIN(sales) dans le WHERE n’a aucun sens puisqu’il n’est pas agrégé au moment de cette condition. Si vous vous retrouvez en entretien et que vous sortez ça, le recruteur risque de lever un sourcil. Correction ? Il suffit d’utiliser HAVING :


SELECT city, MIN(sales)
FROM sales_data
GROUP BY city
HAVING MIN(sales) > 1000;

Voilà, avec HAVING, vous filtrez les résultats après l’agrégation. La leçon ici est cruciale : WHERE ne peut pas contenir d’agrégats, mais HAVING, oui. En entretien, c’est une chance d’impressionner votre interlocuteur en montrant que vous maîtrisez cet aspect fondamental de l’SQL. Ne négligez pas cette différence, car elle peut vous faire passer de héros à just another candidate en un clin d’œil. Lisez aussi cet article pour approfondir le sujet ici.

Quand privilégier les jointures auto-référencées plutôt que les sous-requêtes

Dans le monde du SQL, la question se pose souvent : quand privilégier les jointures auto-référencées plutôt que les sous-requêtes ? La réponse peut sembler complexe, mais en réalité, c’est assez simple : les self-joins peuvent offrir une clarté et des performances nettement supérieures, notamment lorsqu’il s’agit de comparer des données liées dans le temps.

Imaginez que vous surveillez l’évolution des taux de change d’une devise sur plusieurs mois. Vous avez une table taux_change qui enregistre ces valeurs. Pour voir l’évolution d’un mois à l’autre, vous pourriez utiliser une sous-requête. À première vue, cela semble être une solution acceptable. Pourtant, elle peut rapidement devenir inefficace, surtout si votre table grossit au fil du temps. Les sous-requêtes imbriquées peuvent prendre un temps considérable à exécuter, car chaque ligne doit être évaluée indépendamment des autres.

Maintenant, regardons un exemple concret. Voici comment vous pourriez écrire une requête avec une sous-requête :

SELECT a.date, a.taux AS taux_actuel, 
(SELECT b.taux 
 FROM taux_change b 
 WHERE b.date = DATE_SUB(a.date, INTERVAL 1 MONTH)) AS taux_precedent
FROM taux_change a;

Cette requête récupère le taux du mois en cours et celui du mois précédent, en effectuant une sous-requête pour chaque ligne. Si votre table compte des milliers de lignes, c’est armageddon pour performer.

Maintenant, faisons la même chose avec un self-join. Voici comment cela pourrait être fait :

SELECT a.date, a.taux AS taux_actuel, b.taux AS taux_precedent 
FROM taux_change a 
LEFT JOIN taux_change b ON b.date = DATE_SUB(a.date, INTERVAL 1 MONTH);

Avec ce self-join, l’ensemble de la table est traité d’un seul coup, comparant chaque ligne avec celle du mois précédent dans un même mouvement. Le résultat est non seulement plus performant, mais aussi plus lisible.

Alors, à quoi ça rime tout ça ? En choisissant judicieusement entre self-joins et sous-requêtes, vous optimisez non seulement la vitesse des requêtes, mais également leur simplicité. Pas besoin de choisir la complexité inutilement, ça ‘’casse’’ parfois le code. Vous pouvez approfondir ce sujet sur ce lien intéressant.

Pourquoi préférer les CTE aux sous-requêtes imbriquées en SQL complexe

Les CTE, ou Common Table Expressions, sont souvent considérés comme le super-héros des requêtes SQL complexes. Pourquoi ? Parce qu’ils rendent les requêtes bien plus lisibles et maintenables que ces sous-requêtes imbriquées qui peuvent nous donner des migraines. Imaginez-vous dans un entretien, un recruteur vous demande de développer une requête complexe. Vous avez deux options : utiliser un CTE ou une sous-requête chelou. En optant pour le CTE, vous impressionnez la galerie. En choisissant la sous-requête, vous risquez de vous fourvoyer dans un dédale de parenthèses. Alors, on fait quoi ? Penchons-nous sur un exemple pour saisir tout ça.

Imaginons que nous devons extraire les joueurs d’un jeu vidéo en ligne, triés par le nombre de victoires, mais en excluant ceux qui n’ont pas joué un certain nombre de parties. Avec un CTE, la requête est limpide :


WITH PlayerStats AS (
    SELECT player_id, COUNT(game_id) AS game_count, SUM(wins) AS total_wins
    FROM games
    GROUP BY player_id
)
SELECT player_id, total_wins
FROM PlayerStats
WHERE game_count > 10
ORDER BY total_wins DESC;

Cette structure en « étapes » est non seulement facile à lire, mais elle facilite aussi le debugging. Si quelque chose ne va pas, vous pouvez rapidement isoler le problème dans le CTE. Que dire d’une requête avec une sous-requête imbriquée ? La voilà :


SELECT player_id, total_wins
FROM (
    SELECT player_id, COUNT(game_id) AS game_count, SUM(wins) AS total_wins
    FROM games
    GROUP BY player_id
) AS SubQuery
WHERE game_count > 10
ORDER BY total_wins DESC;

Alors, la différence de clarté est frappante. Dans le CTE, chaque partie de la requête est séparée, ce qui vous permet de rapidement comprendre le flux de la logique. Tandis que la sous-requête évoque un véritable casse-tête.

Un dernier point fort en faveur des CTE : la réutilisabilité. Vous pouvez faire appel à un CTE plusieurs fois au sein d’une même requête. En revanche, la sous-requête est un one-shot. Parfois, la simplicité est clé, et c’est exactement ce que les CTE apportent. Si vous cherchez à approfondir sur le sujet, je vous recommande de jeter un œil à ce fil Reddit qui synthétise assez bien cette discussion.

Comment gérer efficacement les NULL et leurs pièges en SQL

Un des concepts les plus négligés, voire mal compris, en SQL est la gestion des valeurs NULL. Une idée reçue, c’est que NULL est simplement une valeur nulle, mais en réalité, NULL évoque l’absence de valeur. Dans la logique conditionnelle, ça change tout ! Si vous essayez de comparer une valeur à NULL avec l’opérateur égal (=), vous allez vous heurter à un mur. La comparaison valeur = NULL retourne toujours FALSE. Pourquoi ? Parce que NULL n’est pas quelque chose, c’est « rien ». Voilà une nuance qui fait souvent échouer les candidats en entretien.

Pour traiter les valeurs NULL, on utilise IS NULL pour vérifier si une colonne a une valeur manquante. Par exemple :

SELECT * FROM table WHERE colonne IS NULL;

Ce code vous ramène toutes les lignes où la colonne spécifiée est NULL. Pratique, non ? Cependant, que faire lorsqu’il faut manipuler ces NULL dans vos calculs, notamment lors d’opérations d’agrégation ? C’est là qu’intervient COALESCE ! Cette fonction est incroyable ; elle vous permet de remplacer une valeur NULL par une autre valeur de votre choix. Ainsi, au lieu d’obtenir un trou béant dans vos résultats, vous obtenez une donnée améliorée.

Imaginons que vous fusionniez deux tables avec un FULL OUTER JOIN. Cela peut générer des NULL si une table n’a pas d’entrée correspondante. Voici un exemple qui éclaire ce point :

SELECT COALESCE(t1.colonne, 'Valeur par défaut') AS colonne_fusionnée
FROM table1 t1
FULL OUTER JOIN table2 t2 ON t1.id = t2.id;

Cette requête permet de créer une colonne fusionnée : si la colonne de table1 est NULL, elle sera remplacée par ‘Valeur par défaut’. C’est une manœuvre essentielle pour éviter de s’emmêler dans les NULL lors de l’analyse des données.

Pour plus d’infos sur la gestion des valeurs NULL, je vous recommande de jeter un œil à cet article qui approfondit le sujet : Gérer les valeurs NULL en SQL. Comprendre ces subtilités pourrait bien faire la différence dans votre prochaine session d’entretien !

Quels bénéfices tirerez-vous en maîtrisant ces concepts clés SQL ?

Maîtriser ces six concepts SQL incontournables — fonctions fenêtres, filtres avec HAVING, self-joins, CTEs, gestion des NULLs, et déduplication par groupes — vous placera nettement en tête des candidats. Non seulement vous éviterez les erreurs classiques, mais vous pourrez aussi écrire des requêtes claires, robustes et performantes, qualités recherchées par les recruteurs. Cet apprentissage vous fera gagner du temps en entretien et en production, renforçant votre crédibilité technique et vos chances de succès.

FAQ

Quelles sont les erreurs courantes avec les fonctions fenêtres SQL ?

Une erreur fréquente est d’oublier la clause ORDER BY dans les fonctions comme LAG() ou RANK(), ce qui conduit à des résultats non déterministes et incorrects, car les lignes ne sont pas ordonnées correctement dans la fenêtre.

Quand utiliser HAVING au lieu de WHERE ?

HAVING sert à filtrer les résultats après agrégation, donc seules les conditions sur des fonctions agrégées comme COUNT(), MIN(), MAX() doivent être placées dans HAVING. WHERE filtre avant l’agrégation et ne supporte pas les fonctions d’agrégation.

Pourquoi privilégier une jointure auto-référencée à une sous-requête ?

Les self-joins sont souvent plus simples à lire, plus performants et plus directs pour comparer des lignes liées dans le temps ou par événement, évitant la complexité et l’imbrication des sous-requêtes.

Quels avantages offrent les CTE par rapport aux sous-requêtes imbriquées ?

Les CTE améliorent la lisibilité et la modularité des requêtes, permettant de fractionner la logique en étapes nommées et réutilisables, contrairement aux sous-requêtes imbriquées qui alourdissent et compliquent la maintenance.

Comment éviter les erreurs liées aux NULL en SQL ?

Il faut utiliser IS NULL ou IS NOT NULL pour tester la présence de NULL, et COALESCE pour substituer une valeur par défaut à NULL, car NULL n’est égal à aucune valeur, même pas à lui-même, ce qui peut fausser les conditions logiques.

 

 

A propos de l’auteur

Franck Scandolera, consultant expert et formateur indépendant en Analytics et Data Engineering, accompagne depuis plus de dix ans les professionnels dans la maîtrise des données et de SQL. Responsable de l’agence webAnalyste et de la formation Formations Analytics, il délivre des formations pragmatiques axées sur l’efficacité métier, avec un focus sur les meilleures pratiques SQL, l’automatisation et la conformité. Son expérience terrain en grands comptes et PME garantit des conseils pointus, applicables immédiatement pour réussir les défis data.

Retour en haut
Formations Analytics