Maison > base de données > tutoriel mysql > Pourquoi 'NOT IN' de MySQL échoue-t-il avec des valeurs NULL sur plusieurs tables et comment puis-je y remédier ?

Pourquoi 'NOT IN' de MySQL échoue-t-il avec des valeurs NULL sur plusieurs tables et comment puis-je y remédier ?

Barbara Streisand
Libérer: 2024-12-26 14:40:10
original
434 Les gens l'ont consulté

Why Does MySQL's

Requête MySQL "NOT IN" sur trois tables : pièges et solutions

Dans MySQL, l'opérateur "NOT IN" est couramment utilisé pour récupérer les enregistrements qui n'existent pas dans une table spécifiée. Cependant, lorsque vous travaillez avec plusieurs tables, il est important d'être conscient de ses pièges potentiels.

Un scénario dans lequel « NOT IN » peut conduire à des résultats inattendus est celui où la table recherchée peut contenir des valeurs NULL. Ce problème a été rencontré lors d’une requête comparant les données des tables « note » et « évaluation ». La requête visait à identifier les enregistrements dans « grade » qui ne correspondaient à aucune entrée dans « évaluation », mais elle n'a renvoyé aucun résultat si le nom « JOHN » n'était pas présent dans les deux tables.

Pour éviter cela problème, il est recommandé d'utiliser des méthodes alternatives telles que NOT EXISTS ou left joins au lieu de "NOT IN". Ces approches ne souffrent pas du risque que les valeurs NULL perturbent la requête.

De plus, il est conseillé d'utiliser des jointures explicites plutôt que la syntaxe héritée qui utilise la clause WHERE pour joindre des tables. Les jointures explicites offrent une plus grande clarté et évitent les problèmes de performances potentiels.

Pour illustrer davantage les inconvénients de « NOT IN » lorsqu'il s'agit de valeurs NULL, considérons l'exemple suivant :

Structure de table :

CREATE TABLE mStatus (
  id INT AUTO_INCREMENT PRIMARY KEY,
  status VARCHAR(10) NOT NULL
);
INSERT INTO mStatus (status) VALUES ('single'),('married'),('divorced'),('widow');

CREATE TABLE people (
  id INT AUTO_INCREMENT PRIMARY KEY,
  fullName VARCHAR(100) NOT NULL,
  status VARCHAR(10) NULL
);
Copier après la connexion

Morceau 1 :

TRUNCATE TABLE people;
INSERT INTO people (fullName, status) VALUES ('John Henry','single');
SELECT * FROM mStatus WHERE status NOT IN (SELECT status FROM people);
Copier après la connexion

Résultat attendu : 3 lignes (comme prévu)

Chronk 2 :

TRUNCATE TABLE people;
INSERT INTO people (fullName, status) VALUES ('John Henry','single'),('Kim Billings',NULL);
SELECT * FROM mStatus WHERE status NOT IN (SELECT status FROM people);
Copier après la connexion

Résultat inattendu : Aucune ligne returnné

Ce comportement inattendu est dû à la logique à trois valeurs utilisée par MySQL. Lorsque des valeurs NULL sont impliquées, la requête se traduit par :

status NOT IN ('single', 'married', 'widowed', NULL)
Copier après la connexion

ce qui équivaut à :

NOT(status='single' OR status='married' OR status='widowed' OR status=NULL)
Copier après la connexion

Puisque l'expression "status=NULL" est évaluée à INCONNU, l'expression entière devient INCONNU, et toutes les lignes sont filtrées out.

Solution :

Pour éviter ce problème, utilisez des approches alternatives telles que les jointures à gauche ou NOT EXISTS :

SELECT s.status
FROM mStatus s
LEFT JOIN people p ON p.status=s.status
WHERE p.status IS NULL
Copier après la connexion

ou

SELECT s.status
FROM mStatus s
WHERE NOT EXISTS (SELECT 1 FROM people p WHERE p.status=s.status)
Copier après la connexion

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