web-dev-qa-db-fra.com

PAS LIKE et LIKE ne retournant pas le résultat inverse

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.

58
Shanka

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
73
sagi

(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.

18
Salman A

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%'
2
infectious
  1. Select * from tbl1 
    WHERE ([TextCol] NOT LIKE '%TAX%') AND ([TextCol] NOT LIKE '%TAX%')
    
  2. select * from tbl1
    where [TextCol] NOT LIKE '%TAX%' OR [TextCol] IS NULL
    
1
Chanukya

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.

0
Yossi Orsen

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) 
0
Tomas Hesse