Почему знак равенства MySQL совпадает с неправильными записями?
Я запускаю запрос на выборку для двух таблиц и ищу соответствующие записи со знаком равенства. В моем понимании, MySQL должен возвращать только записи, точно соответствующие условию WHERE, однако он возвращает записи, например, когда я использую оператор LIKE:
Любые объяснения, почему первая строка будет возвращена в результате запроса?
РЕДАКТИРОВАТЬ:
Вот запрос:
SELECT `ts`.`ticker_symbol`, `sm`.`id` AS `matchescount`, `sm`.`ticker_symbol_ids`
FROM `mk_ticker_symbols` `ts`, `mk_submissions` `sm`
WHERE `sm`.`ticker_symbol_ids` = `ts`.`id` AND `ts`.`id` = "1506"
РЕДАКТИРОВАТЬ 2: Вот SQL Fiddle: http://sqlfiddle.com/
РЕДАКТИРОВАТЬ 3: Вот SQL Fiddle с JOINs: http://sqlfiddle.com/
4 ответа
Пьеро, тот что с JOIN может быть исправлен. CAST()
в JOIN
исправит проблему.
INNER JOIN `mk_submissions` `sm`
ON `sm`.`ticker_symbol_ids` = CAST(`ts`.`id` AS CHAR(10))
Я знаю, что вы не ищете решение, но я все еще публикую его.
Проблема очень интересная. Я искал в Интернете и сделал несколько пробных ошибок в моей БД. У меня нет объяснений.... Я пытался поставить 1506,
во втором или третьем месте в списке через запятую - запрос работает нормально. Итак, у меня есть ощущение, что в случае JOIN
со списком через запятую запятая обрабатывается как подстановочный знак "конец строки"...
Если вы когда-нибудь найдете объяснение, пожалуйста, опубликуйте его здесь.
При оценке выражений MySQL преобразует оба аргумента (в данном случае) в числа с плавающей запятой, чтобы сравнить их. Это потому, что один является строкой, а другой - целым числом, что приводит к применению последнего условия в приведенной выше ссылке.
Во всех других случаях аргументы сравниваются как числа с плавающей точкой (действительные).
Так что же является эквивалентом строки с плавающей точкой "1506,..."?
Выполнение следующего на моем тестовом сервере:
SELECT "1506,3101,26673,26745,2277,1216,26847,26865,20711,1468,26947,233,20539,26985"+0.0
Результаты в:
1506
Что, конечно, равно версии целого числа 1506 с плавающей запятой.
Итак, все ведет себя как ожидалось. По крайней мере, предполагая, что вы ожидаете, что это сравнение с плавающей запятой произойдет.
Я нашел ответ на этот вопрос. Я сравнивал строку с целым числом здесь:
`sm`.ticker_symbol_ids` = `ts` `id` И` ts``id` = "1506"
Проблема заключается в том, что это преобразуется внутри целого числа для сравнения: 1506,3101,26673,26745,2277,1216,26847,26865,20711,1468,26947,233,20539,26985
Из-за запятой MySQL считает, что это десятичная дробь или число с плавающей запятой, и все, что после запятой, для сравнения опущено. Так становится 1506
вместо 1506,3101,26673,26745,2277,1216,26847,26865,20711,1468,26947,233,20539,26985
и это соответствует WHERE
состояние.
@cyadvert и @Willem_Renzema были абсолютно правильными.
Чтобы решить проблему, мне нужно было только:
CAST (`ts`.id` AS CHAR)
Я не могу дать полное объяснение проблемы, но у меня есть решение.
ts.id
вероятно, и INTEGER, так что ваше предложение where должно быть
`ts`.`id` = 1506
(удалить кавычки из числа).
Также вы должны использовать соединение вместо предложения where для соответствия таблицам:
FROM `mk_ticker_symbols` `ts`
JOIN `mk_submissions` `sm` on sm.ticker_symbol_ids = ts.id