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
DDDoriginal
2025-01-18 11:26:12819parcourir

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] :

<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 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 :
<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>
  1. Utilisation de NOT EXISTS : Remplacez NOT IN par NOT EXISTS pour une approche potentiellement plus efficace et plus claire :
<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>

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:
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