J'ai une table avec 200 enregistrements dont 10 ont un texte contenant le mot "TAX".
Quand j'exécute
Select * from tbl1 WHERE [TextCol] LIKE '%TAX%'
puis j'obtiens le jeu de résultats avec ces 10 enregistrements correctement.
Mais quand j'essaie d'exclure ces enregistrements par
Select * from tbl1 WHERE [TextCol] NOT LIKE '%TAX%'
il ne renvoie que 100 enregistrements au lieu de 190.
Est-ce que cela renvoie le résultat correct?
Select * from tbl1 WHERE COALESCE([TextCol],'-1') NOT LIKE '%TAX%'
Je crois que les valeurs NULL
sont le problème ici. Si la colonne les contient, NULL NOT LIKE '%TAX%'
renverra UNKNOWN/NULL
et ne sera donc pas sélectionné.
Je vous conseille de lire sur le traitement avec les valeurs NULL
ou ici .
Comme @ughai l'a suggéré, si les performances sont un problème, vous pouvez également utiliser:
Select * from tbl1
WHERE [TextCol] NOT LIKE '%TAX%'
OR [TextCol] IS NULL
(A) Les opérateurs de comparaison SQL donnent trois valeurs possibles: True, False et Unknown. Si un ou les deux opérandes sont NULL
, le résultat est Unknown. Prenons l'exemple suivant où nous comparons certaines valeurs (l'âge d'une personne) à une constante (18):
21 >= 18 -- True
15 >= 18 -- False
NULL >= 18 -- Unknown
Comme vous pouvez le constater, la base de données ne peut/ne décidera pas si NULL
est supérieur/égal à 18.
(B) La base de données ne renverra que les lignes pour lesquelles la clause WHERE
est évaluée à True. L'inversion de l'expression (par exemple, WHERE age >= 18
modifié en WHERE age < 18
) n'affecte pas les résultats inconnus.
Vous pouvez utiliser le IS [NOT] NULL
pour faire correspondre les valeurs NULL
. La requête suivante sélectionnera les lignes pour lesquelles la colonne ne correspond pas au modèle OR, la colonne est NULL:
WHERE [TextCol] NOT LIKE '%TAX%' OR [TextCol] IS NULL
Des fonctions telles que ISNULL
et COALESCE
peuvent être utilisées pour transformer NULL
en une valeur.
Cela m'arrive aussi une fois! après avoir brisé ma tête, j'ai découvert que c'était à cause de valeurs nulles, vous pouvez donc utiliser cette requête pour l'éviter:
WHERE CASE WHEN [TextCol] IS NULL
THEN 'default'
ELSE [TextCol]
END NOT LIKE '%TAX%'
Select * from tbl1
WHERE ([TextCol] NOT LIKE '%TAX%') AND ([TextCol] NOT LIKE '%TAX%')
select * from tbl1
where [TextCol] NOT LIKE '%TAX%' OR [TextCol] IS NULL
Vous devez également vérifier les valeurs NULL:
[TextCol] NOT LIKE '%TAX%' OR [TextCol] IS NULL
Cela devrait également prendre en compte les valeurs nulles, ce qui explique probablement pourquoi vous n’avez pas obtenu toutes les lignes de la sortie.
J'ai eu le même problème avec l'opérateur IN
sur la colonne simple int avec NULL . J'ai trouvé que ceux-ci n'étaient pas inverses comme je le pensais. (Je pourrais dire par le nombre de lignes)
select * from Dest where id in(select id from Source)
select * from Dest where id NOT in(select id from Source)
Pour me faire intervertir, je devais aussi les réécrire en tant que tels:
select * from Dest where isnull(id,-2) in(select isnull(id,-1) from Source)
select * from Dest where isnull(id,-2) NOT in(select isnull(id,-1) from Source)