Maison >base de données >tutoriel mysql >Pourquoi ma requête SQL `NOT IN` ne renvoie-t-elle aucun résultat lorsque des valeurs NULL existent dans la sous-requête ?
La clause NOT IN
de SQL et le problème de la valeur NULL
L'opérateur NOT IN
en SQL est conçu pour sélectionner les lignes dans lesquelles la valeur d'une colonne n'est pas trouvée dans un ensemble de valeurs spécifié. Cependant, cet opérateur se comporte de manière inattendue lorsque l'ensemble de comparaison contient des valeurs NULL
. Cet article explique ce comportement et propose des solutions.
Le problème :
Considérons un scénario dans lequel vous essayez de trouver des produits dans une base de données (Inventory
) qui ne sont pas présents dans une base de données de sous-ensemble (Subset
). Une approche courante utilisant NOT IN
pourrait ressembler à ceci :
<code class="language-sql">SELECT stock.IdStock, stock.Descr FROM [Inventory].[dbo].[Stock] stock WHERE stock.IdStock NOT IN (SELECT foreignStockId FROM [Subset].[dbo].[Products]);</code>
Si la sous-requête (SELECT foreignStockId FROM [Subset].[dbo].[Products]
) renvoie des valeurs NULL
, la condition NOT IN
entière devient indéterminée, ce qui entraîne un ensemble de résultats vide, même s'il y a des valeurs IdStock
dans [Inventory].[dbo].[Stock]
qui sont pas présent en [Subset].[dbo].[Products]
.
Pourquoi cela se produit :
SQL utilise une logique à trois valeurs : TRUE
, FALSE
et UNKNOWN
. Lorsque l'on compare une valeur à NULL
, le résultat est toujours UNKNOWN
. NOT IN
vérifie essentiellement si une valeur est FALSE
pour toutes comparaisons. Puisque UNKNOWN
n'est pas FALSE
, tout NULL
dans l'ensemble de résultats de la sous-requête fait que l'intégralité de la condition NOT IN
est évaluée comme un ensemble vide.
Solutions :
Pour éviter ce problème, utilisez l'une des méthodes suivantes :
1. Exclure explicitement les valeurs NULL : Modifiez la sous-requête pour filtrer les NULL
valeurs :
<code class="language-sql">SELECT stock.IdStock, stock.Descr FROM [Inventory].[dbo].[Stock] stock WHERE stock.IdStock NOT IN (SELECT foreignStockId FROM [Subset].[dbo].[Products] WHERE foreignStockId IS NOT NULL);</code>
2. Utiliser NOT EXISTS
: Cette approche est généralement privilégiée pour sa clarté et son efficacité :
<code class="language-sql">SELECT stock.IdStock, stock.Descr FROM [Inventory].[dbo].[Stock] stock WHERE NOT EXISTS (SELECT * FROM [Subset].[dbo].[Products] p WHERE p.foreignStockId = stock.IdStock);</code>
La clause NOT EXISTS
vérifie si aucune lignes n'existent dans la sous-requête qui correspondent à la condition. Il gère les valeurs NULL
correctement sans nécessiter d'exclusion explicite.
En comprenant l'interaction entre les valeurs NULL
et l'opérateur NOT IN
, vous pouvez écrire des requêtes SQL plus robustes et plus fiables. L'alternative NOT EXISTS
est souvent la solution la plus propre et la plus efficace lorsqu'il s'agit de valeurs NULL
potentielles dans l'ensemble de comparaison.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!