Maison > base de données > tutoriel mysql > Pourquoi ma clause SQL `NOT IN` ne renvoie-t-elle pas les résultats attendus ?

Pourquoi ma clause SQL `NOT IN` ne renvoie-t-elle pas les résultats attendus ?

Barbara Streisand
Libérer: 2025-01-18 11:36:09
original
462 Les gens l'ont consulté

Why Does My SQL `NOT IN` Clause Fail to Return Expected Results?

Dépannage de la clause NOT IN de SQL : pourquoi elle pourrait échouer et comment y remédier

La clause SQL NOT IN est conçue pour sélectionner des lignes d'une table qui n'existent pas dans une autre. Cependant, un comportement inattendu peut survenir, notamment lorsqu'il s'agit de NULL valeurs.

Analysons cette requête problématique :

<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>
Copier après la connexion

Cette requête peut ne renvoyer aucun résultat, même si elle doit exclure certains enregistrements.

La cause profonde : NULLLes valeurs

Le problème vient des NULL valeurs dans la colonne foreignStockId du tableau Products. L'opérateur NOT IN de SQL se comporte de manière imprévisible avec les NULL. Une comparaison impliquant NULL aboutit toujours à UNKNOWN, ce qui à son tour affecte la logique booléenne globale de la clause WHERE.

Solutions efficaces :

Voici deux méthodes fiables pour corriger cela :

  1. Filtrer les NULL s : Modifier la sous-requête pour exclure explicitement 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>
Copier après la connexion
  1. Utilisation de NOT EXISTS : Cet opérateur offre une alternative plus robuste et souvent plus efficace :
<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>
Copier après la connexion

NOT EXISTS vérifie directement l'absence de lignes correspondantes, évitant ainsi la complexité des NULL comparaisons.

Optimisation des performances :

Bien que les deux solutions soient correctes, leurs performances peuvent varier. NOT EXISTS conduit généralement à des plans d'exécution plus simples et potentiellement plus rapides, en particulier avec de grands ensembles de données. Cependant, si votre colonne foreignStockId est exempte de valeurs NULL, NOT IN pourrait fonctionner légèrement mieux. Il est préférable de tester les deux approches dans votre environnement spécifique pour déterminer la solution optimale.

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!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal