Maison > base de données > tutoriel mysql > Pourquoi mes requêtes SQL « NOT IN » échouent-elles lorsque des valeurs NULL sont présentes ?

Pourquoi mes requêtes SQL « NOT IN » échouent-elles lorsque des valeurs NULL sont présentes ?

DDD
Libérer: 2025-01-18 11:26:12
original
875 Les gens l'ont consulté

Why Do My SQL `NOT IN` Queries Fail When NULL Values Are Present?

Dépannage NOT IN Requêtes et valeurs NULL

Lors de l'interrogation d'une base de données pour rechercher des enregistrements absents dans un sous-ensemble, l'utilisation de NOT IN peut produire des résultats vides inattendus. Cela se produit souvent lorsque la sous-requête contient des valeurs NULL.

Le problème : NOT IN et NULL

Considérez cette requête SQL conçue pour récupérer les enregistrements de [Inventory].[dbo].[Stock] qui ne sont pas présents dans [Subset].[dbo].[Products] :

SELECT stock.IdStock, stock.Descr
FROM   [Inventory].[dbo].[Stock] stock
WHERE  stock.IdStock NOT IN (SELECT foreignStockId
                            FROM   [Subset].[dbo].[Products])
Copier après la connexion

Si foreignStockId contient des valeurs NULL, cette requête ne peut renvoyer aucune ligne, même s'il existe des correspondances. Cela est dû à la logique à trois valeurs de SQL ; une comparaison avec NULL donne UNKNOWN, affectant l'évaluation NOT IN.

La solution : gérer les NULL

Deux solutions efficaces évitent ce problème :

  1. Filtrage des NULL de la sous-requête : Modifiez la sous-requête pour exclure les NULL à l'aide de IS NOT NULL :
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)
Copier après la connexion
  1. Utilisation de NOT EXISTS : Remplacez NOT IN par NOT EXISTS pour une approche potentiellement plus efficace et plus claire :
SELECT stock.idstock, stock.descr
FROM   [Inventory].[dbo].[Stock] stock
WHERE  NOT EXISTS (SELECT *
                   FROM   [Subset].[dbo].[Products] p
                   WHERE  p.foreignstockid = stock.idstock)
Copier après la connexion

Performances :

NOT EXISTS produit souvent des plans d'exécution plus simples, conduisant potentiellement à de meilleures performances, en particulier lorsqu'il s'agit de NULL.

Lectures complémentaires :

Pour des comparaisons plus approfondies des différentes approches de ce problème, y compris LEFT JOIN et d'autres alternatives, consultez ces ressources :

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!

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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal