Lorsque vous travaillez avec des requêtes SQL Server, il est important de comprendre les subtilités des différents opérateurs et leur impact sur les résultats. Un tel opérateur est l’opérateur “Différent de” (<>), qui est couramment utilisé pour filtrer les données et exclure certaines lignes des résultats de la requête. Cependant, il existe des cas où l’utilisation de cet opérateur peut entraîner des résultats inattendus.
Prenons en compte un scénario où un centre de test enregistre des étudiants pour des examens informatiques. Chaque étudiant peut passer plusieurs examens, et nous avons deux tables : “Étudiants” et “ExamenÉtudiant”. La table “Étudiants” stocke des informations sur les étudiants, tandis que la table “ExamenÉtudiant” enregistre les examens passés par chaque étudiant.
Voici un exemple de création et de peuplement de ces tables :
CREATE TABLE Étudiants (
StID INT PRIMARY KEY,
StName NVARCHAR(50)
)
INSERT INTO Étudiants VALUES (1,'Jack')
INSERT INTO Étudiants VALUES (2,'Anna')
INSERT INTO Étudiants VALUES (3,'Bob')
CREATE TABLE ExamenÉtudiant (
StID INT,
NomExamen VARCHAR(50)
)
INSERT INTO ExamenÉtudiant VALUES (1,'SQL Server')
INSERT INTO ExamenÉtudiant VALUES (2,'VB.NET')
INSERT INTO ExamenÉtudiant VALUES (2,'C#.NET')
INSERT INTO ExamenÉtudiant VALUES (1,'XML')
Maintenant, supposons que l’on nous demande de préparer un rapport qui liste les informations des étudiants qui ont passé l’examen SQL Server. Nous pouvons y parvenir en utilisant la requête suivante :
SELECT s.*
FROM Étudiants s
JOIN ExamenÉtudiant ee ON s.StID = ee.StID
WHERE ee.NomExamen = 'SQL Server'
Cette requête renverra correctement les informations des étudiants qui ont passé l’examen SQL Server.
Cependant, le problème se pose lorsque l’on nous demande de rechercher les étudiants qui n’ont PAS passé l’examen SQL Server. L’instinct premier pourrait être de remplacer l’opérateur “Égal” dans la clause WHERE par l’opérateur “Différent de” :
SELECT s.*
FROM Étudiants s
JOIN ExamenÉtudiant ee ON s.StID = ee.StID
WHERE ee.NomExamen <> 'SQL Server'
Étonnamment, cette requête ne produit pas le résultat attendu. Elle renvoie Jack, qui a passé l’examen XML, ce qui satisfait la condition de la clause WHERE. Cela se produit parce que l’opérateur “Différent de” ne tient pas compte de la relation entre les tables et inclut les lignes qui ont un nom d’examen différent, même si elles appartiennent au même étudiant.
Pour récupérer correctement les étudiants qui n’ont PAS passé l’examen SQL Server, nous devons utiliser une approche différente. Une façon de faire est d’utiliser une sous-requête pour construire une liste des étudiants qui ont passé l’examen SQL Server, puis de sélectionner les étudiants qui n’apparaissent pas dans cette liste :
SELECT *
FROM Étudiants
WHERE StID NOT IN (
SELECT StID
FROM ExamenÉtudiant
WHERE NomExamen = 'SQL Server'
)
Cette requête garantit que seuls les étudiants qui n’apparaissent pas dans la liste de ceux qui ont passé l’examen SQL Server sont renvoyés dans le rapport.
Alternativement, nous pouvons obtenir le même résultat en utilisant une jointure externe :
SELECT s.*
FROM Étudiants s
LEFT JOIN (
SELECT StID
FROM ExamenÉtudiant
WHERE NomExamen = 'SQL Server'
) ee ON s.StID = ee.StID
WHERE ee.StID IS NULL
En utilisant une jointure externe et en vérifiant les valeurs NULL dans la table jointe, nous pouvons récupérer efficacement les étudiants qui n’ont PAS passé l’examen SQL Server.
Il est important d’être prudent lors de l’utilisation de l’opérateur “Différent de” dans les requêtes SQL Server, en particulier lorsqu’il s’agit de jointures de type un-à-plusieurs. Comprendre la relation entre les tables et prendre en compte le résultat souhaité est crucial pour éviter des résultats inattendus.
N’oubliez pas d’analyser attentivement les exigences de votre requête et de choisir l’approche appropriée pour obtenir les résultats souhaités.