Pourquoi utiliser un caractère de soulignement dans un filtre LIKE me donne tous les résultats?


118

J'ai écrit la requête SQL ci-dessous avec une LIKEcondition:

SELECT * FROM Manager
WHERE managerid LIKE '_%'
AND managername LIKE '%_%'

Dans le LIKEJe veux rechercher des traits de soulignement %_%, mais je sais que les données de mes colonnes n'ont pas de caractères de soulignement.

  • Pourquoi la requête me donne-t-elle tous les enregistrements de la table?

Exemple de données:

create table Manager(
    id int
    ,managerid varchar(3)
    ,managername varchar(50)
    );

insert into Manager(id,managerid,managername)values(1,'A1','Mangesh');
insert into Manager(id,managerid,managername)values(2,'A2','Sagar');
insert into Manager(id,managerid,managername)values(3,'C3','Ahmad');
insert into Manager(id,managerid,managername)values(4,'A4','Mango');
insert into Manager(id,managerid,managername)values(5,'B5','Sandesh');

Sql-Fiddle


1
C'est bien d'ajouter une requête sql-fiddle, mais vous devez toujours afficher la requête sur SO sous forme de texte brut. Sinon, cette question est vulnérable à la pourriture des liens .
Tim Schmelter

_ :: Un substitut pour un seul personnage
vhadalgi

Réponses:


193

Modifiez votre WHEREcondition comme ceci:

WHERE mycolumn LIKE '%\_%' ESCAPE '\'

C'est l'une des manières dont Oracle prend en charge les caractères d'échappement. Ici, vous définissez le caractère d'échappement avec le escapemot - clé. Pour plus de détails, consultez ce lien sur Oracle Docs .

Les '_'et '%'sont des caractères génériques dans une LIKEinstruction opérée en SQL.

Le _personnage recherche la présence de (n'importe quel) caractère unique. Si vous effectuez une recherche par columnName LIKE '_abc', il vous donnera résultat avec des lignes ayant 'aabc', 'xabc', '1abc', '#abc'mais pas 'abc', 'abcc', 'xabcd'et ainsi de suite.

Le '%'caractère est utilisé pour faire correspondre 0 ou plusieurs nombres de caractères. Cela signifie que , si vous effectuez une recherche par columnName LIKE '%abc', il vous donnera résultat avec avoir 'abc', 'aabc', 'xyzabc'et ainsi de suite, mais pas'xyzabcd' , 'xabcdd'et toute autre chaîne qui ne se termine pas avec 'abc'.

Dans votre cas, vous avez recherché par '%_%'. Cela donnera toutes les lignes avec cette colonne ayant un ou plusieurs caractères, c'est-à-dire tous les caractères, comme valeur. C'est pourquoi vous obtenez toutes les lignes même s'il n'y a aucune valeur _dans vos colonnes.


Je suis confronté au même problème dans l'accès Db. pouvez s'il vous plaît me dire comment je peux résoudre ce problème.

Peut-être que vous pouvez rechercher des «caractères génériques dans la base de données d'accès» sur Google. Je n'ai jamais travaillé sur Access, donc je ne peux pas vous aider avec ça. Je doute même si Access prend en charge l' likeopérateur. Ma solution fonctionnera dans la plupart des bases de données, sinon dans toutes.
Rachcha

2
Ce qui n'est pas indiqué ici, c'est que cela fonctionne également sur SQL Server - ce qui m'a initialement laissé perplexe sur les raisons pour lesquelles l'OP a accepté une réponse pour Oracle SQL, quand ils ont eux-mêmes étiqueté la question pour SQL Server. Au moins, la réponse doit être écrite pour cibler principalement le SGBD balisé à l'origine.
underscore_d

87

Le trait de soulignement est le caractère générique dans uneLIKE requête pour un caractère arbitraire.

Par conséquent LIKE %_%signifie "donnez-moi tous les enregistrements avec au moins un caractère arbitraire dans cette colonne".

Vous devez échapper le caractère générique, dans sql-server avec []environ:

SELECT m.* 
FROM Manager m 
WHERE m.managerid    LIKE  '[_]%'
AND   m.managername  LIKE '%[_]%'

Voir: LIKE (Transact-SQL)

Demo


Merci d'avoir fourni le lien MSDN dans votre réponse. J'avais du mal à trouver des informations sur les caractères spéciaux de soulignement jusqu'à ce que je lis votre message.
Chris Smith

5
C'est la bonne réponse car l'utilisateur a spécifié la sql-serverbalise dans sa question et le SQLFiddle fourni est également désigné comme MS SQL Server 2008.
Govind Rai

8

Comme vous voulez rechercher spécifiquement un caractère générique, vous devez échapper à cela

Cela se fait en ajoutant la ESCAPEclause à votre LIKEexpression. Le caractère spécifié avec leESCAPE clause "invalidera" le caractère générique suivant.

Vous pouvez utiliser n'importe quel caractère que vous aimez (mais pas un caractère générique). La plupart des gens utilisent un \parce que c'est ce que de nombreux langages de programmation utilisent également

Ainsi, votre requête entraînerait:

select * 
from Manager
where managerid LIKE '\_%' escape '\'
and managername like '%\_%' escape '\';

Mais vous pouvez tout aussi bien utiliser n'importe quel autre caractère:

select * 
from Manager
where managerid LIKE '#_%' escape '#'
and managername like '%#_%' escape '#';

Voici un exemple SQLFiddle: http://sqlfiddle.com/#!6/63e88/4


5

Le soulignement est un joker pour quelque chose. par exemple 'A_%' recherchera toutes les correspondances commençant par 'A' et aura au moins 1 caractère supplémentaire après cela


0

Vous pouvez écrire la requête comme ci-dessous:

SELECT * FROM Manager
WHERE managerid LIKE '\_%' escape '\'
AND managername LIKE '%\_%' escape '\';

cela résoudra votre problème.


Comment cela ajoute-t-il quelque chose au-delà de la réponse acceptée?
Noah Broyles le

0

Au cas où les gens chercheraient comment le faire dans BigQuery:

  • Un trait de soulignement "_" correspond à un seul caractère ou octet.

  • Vous pouvez échapper "\", "_" ou "%" en utilisant deux barres obliques inverses. Par exemple, "\%". Si vous utilisez des chaînes brutes, une seule barre oblique inverse est requise. Par exemple, r "\%".

WHERE mycolumn LIKE '%\\_%'

Source: https://cloud.google.com/bigquery/docs/reference/standard-sql/operators

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.