Почему «_» (подчеркивание) соответствует «-» (дефис)?

110

Мне нужно найти руководство в формате PDF, используя этот запрос:

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)

Почему, когда я указываю имя, я вижу то, что обозначено тире taz_manual%.pdf?

НАПРИМЕР
источник

Ответы:

231

Поскольку подчеркивание _- это подстановочный знак, такой как процент %, за исключением того, что он ищет только один символ.

Сопоставление с шаблоном SQL позволяет использовать «_» для сопоставления любого отдельного символа и «%» для сопоставления произвольного количества символов (включая нулевые символы).

(Из раздела 3.3.4.7. Сопоставление с образцом в документации MySQL.)

Если вы хотите использовать символ подчеркивания в likeкачестве литерала, вы должны его избежать:

select * from a where name like '%taz\_manual%.pdf%';
Книга Зевса
источник
afaik, это актуально только тогда, когда вы находитесь в контексте шаблона. например, внутри LIKEзаявления. При замене всех _с -: UPDATE sys_file set identifier = REPLACE(identifier, '_', '-') WHERE identifier LIKE '%\_%';. Обратите внимание на побег внутри LIKEи на отсутствие побега внутрь REPLACE. (Мне кажется странным, что вы не находитесь в контексте шаблона внутри replace ...)
Hafenkranich
@Hafenkranich из документа mysql: «используйте операторы сравнения LIKE или NOT LIKE»
Книга Зевса
2

У меня была аналогичная проблема с пробелом и дефисами при сопоставлении строк с точным соответствием:

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

Вышеупомянутый запрос не вернул никаких записей в MySQL. Мне пришлось избегать пробелов и дефисов и использовать LIKEвместо точного совпадения equals (=) следующим образом:

SELECT id FROM location WHERE name LIKE 'IND_\-_HQ';
NBhat
источник
Вы уверены, что это связано? Может, не было строки локации с таким точным названием ... ???
Нико Хаасе
да, там были строки с location = 'IND - HQ', и вышеупомянутая проблема
устранила возникшую
И вы знаете это, потому что вы спросили человека, у которого был этот вопрос, за пять лет до того, как опубликовали свой ответ?
Нико Хаасе