У меня есть эта таблица Tags
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. Помогите.
MySQL поддерживает два варианта case: тот, который вы используете в запросе 2, менее гибкий, но поддерживает только равенство по одной переменной. Другая версия не определяет никаких переменных после case, и тогда условия не должны быть только равенством:
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%"
См. документацию для получения дополнительной информации
EDIT: Вот еще немного объяснений того, почему ваш запрос №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
ожидает получить буквальное значение для сравнения между , когда ... затем
В приведенном выше случае оцениваются выражения tag LIKE "% class%"
, tag LIKE "% new%"
и tag LIKE "% pack%"
. перед фактическим сравнением случаев.
Однако (!) Происходит то, что они становятся либо 0, либо 1, и по сравнению со значением тега это первое значение 0, которое будет соответствовать любому char (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 здесь является стандартной ловушкой.