ПЕРЕКЛЮЧЕНИЕ с LIKE внутри запроса SELECT в MySQL - PullRequest
25 голосов
/ 21 июня 2010

У меня есть таблица тегов

CREATE TABLE IF NOT EXISTS `Tags` (
   `id_tag` int(10) unsigned NOT NULL auto_increment,
   `tag` varchar(255) default NULL,
   PRIMARY KEY  (`id_tag`),
   UNIQUE KEY `tag` (`tag`),
   KEY `id_tag` (`id_tag`),
   KEY `tag_2` (`tag`),
   KEY `tag_3` (`tag`),
   KEY `tag_4` (`tag`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=2937 ;

INSERT INTO `Tags` (`id_tag`, `tag`) VALUES
   (1816, '(class'),
   (2642, 'class\r\n\r\nâ?¬35'),
   (1906, 'class\r\nif'),
   (1398, 'class'),
   (2436, 'class)'),
   (1973, 'class:\n1.'),
   (2791, 'classes'),
   (1325, 'New'),
   (2185, 'pack'),
   (1905, 'packed'),
   (1389, 'WebClass');

Я хочу получить все записи, в которых тег соответствует ключевым словам class или pack или new, а также другое поле, которое указывает, какое из 3 ключевых слов действительно соответствует полю тега.

Следующий запрос не дает правильных результатов Запрос 1

select id_tag,
case tag 
   when tag LIKE "%class%" then "class" 
   when tag LIKE "%new%" then "new"
   when tag LIKE "%pack%" then "pack"
end as matching_tag 
from Tags 
where tag LIKE "%class%" OR tag LIKE "%new%" OR tag LIKE "%pack%"

Я должен использовать подобное внутри корпуса. В противном случае завершите согласование работ. Следующий запрос работает: -

Запрос 2

select id_tag,
case tag 
   when "class" then "class" 
   when "new" then "new"
   when "pack" then "pack"
end as matching_tag 
from Tags 
where tag = "class" OR tag = "new" OR tag = "pack"

Что не так с запросом 1. Пожалуйста, помогите.

Ответы [ 2 ]

36 голосов
/ 21 июня 2010

Mysql поддерживает два варианта case, тот, который вы используете в запросе 2, менее гибок, но поддерживает только равенство для одной переменной.Другая версия не определяет переменную после регистра, и тогда условия не обязательно должны быть только равенством:

select id_tag,
case  
   when tag LIKE "%class%" then "class" 
   when tag LIKE "%new%" then "new"
   when tag LIKE "%pack%" then "pack"
end as matching_tag 
from Tags 
where tag LIKE "%class%" OR tag LIKE "%new%" OR tag LIKE "%pack%"

Подробнее см. документация

РЕДАКТИРОВАТЬ: Вот немного больше объясненияпочему ваш запрос # 1 возвратил то, что он возвратил:

case tag
   when tag LIKE "%class%" then "class" 
   when tag LIKE "%new%" then "new"
   when tag LIKE "%pack%" then "pack"
end as matching_tag

ожидает получить литеральное значение для сравнения между when ... then В приведенном выше случае выражения tag LIKE "%class%", tag LIKE "%new%" и tag LIKE "%pack%"все оценивается до фактического сравнения случаев.Однако (!) Происходит то, что они становятся равными 0 или 1, и по сравнению со значением тега это первое значение 0, которое будет соответствовать любому символу (char будет приведен к 0) - это согласуется с результатамивашего первого запроса.

Вот запрос, который показывает логические значения для соответствующих выражений:

select id_tag, tag LIKE "%class%", tag LIKE "%new%", tag = 0, case tag     when tag LIKE "%class%" then "class"     when tag LIKE "%new%" then "new"    when tag LIKE "%pack%" then "pack" end as matching_tag  from Tags  where tag LIKE "%class%" OR tag LIKE "%new%" OR tag LIKE "%pack%";

Вот почему вы получаете неожиданные результаты;тихий CAST - стандартная ловушка здесь.

13 голосов
/ 09 января 2015

Просто хочу напомнить, о другом предложении:

case  
   when tag LIKE "%class%" then "class" 
   when tag LIKE "%new%" then "new"
   when tag LIKE "%pack%" then "pack"
   else "no one"
end as matching_tag 
...