¿Por qué "_" (guión bajo) coincide con "-" (guión)?

110

Tengo que buscar un manual en PDF usando esta consulta:

root@localhost:test> select * from a where name like '%taz_manual%.pdf%';
+--------------------+------------------+-------------+
| name               | description      |        size | 
+--------------------+------------------+-------------+
| taz-manual-1.1.pdf | Manual v1.0 TA-Z |    31351902 |
| taz-manual-0.2.pdf | Manual v1.0 T1-A |     3578278 |
| taz_manual-2.0.pdf | Manual v2.0 GA-X |   542578278 |
etc........
+--------------------+------------------+-------------+
132 row in set (0.00 sec)

¿Por qué veo el que tiene guiones cuando especifico el nombre taz_manual%.pdf?

P.EJ
fuente

Respuestas:

231

Porque el guión bajo _es un comodín como el porcentaje %, excepto que solo busca un carácter.

La coincidencia de patrones SQL le permite usar "_" para hacer coincidir cualquier carácter individual y "%" para hacer coincidir un número arbitrario de caracteres (incluido cero caracteres).

(De la sección 3.3.4.7. Coincidencia de patrones en la documentación de MySQL).

Si desea usar el guión bajo likecomo literal, debe escapar de él:

select * from a where name like '%taz\_manual%.pdf%';
Libro de Zeus
fuente
afaik, esto solo es relevante cuando estás en un contexto de patrón. por ejemplo, dentro de una LIKEdeclaración. Al reemplazar todo _con un -: UPDATE sys_file set identifier = REPLACE(identifier, '_', '-') WHERE identifier LIKE '%\_%';. Note el escape adentro LIKEy no escape adentro REPLACE. (Me parece extraño que no estés en un contexto de patrón dentro de reemplazar ...)
Hafenkranich
@Hafenkranich del documento de mysql: "use los operadores de comparación LIKE o NOT LIKE"
Libro de Zeus
2

Tuve un problema similar con el espacio y los guiones al hacer coincidir cadenas con una coincidencia exacta:

SELECT id FROM location WHERE name = 'IND - HQ';

La consulta anterior no devolvió ningún registro en MySQL. Tuve que escapar de los espacios y guiones y usar en LIKElugar de la coincidencia exacta con iguales (=) de la siguiente manera:

SELECT id FROM location WHERE name LIKE 'IND_\-_HQ';
NBhat
fuente
¿Estás seguro de que esto está relacionado? Tal vez no había una fila de ubicación con este nombre exacto ... ???
Nico Haase
sí, había filas con location = 'IND - HQ' y lo anterior solucionó el problema al que se enfrentaba
NBhat
¿Y lo sabes porque le preguntaste a la persona que tenía esta pregunta cinco años antes de publicar tu respuesta?
Nico Haase