MySQL возвращает несколько строк, которые не соответствуют критериям поиска - PullRequest
4 голосов
/ 06 июня 2019

У меня установлен MySQL локально, при запуске SELECT VERSION() возвращает это значение: 5.6.43-84.3

Когда я запускаю запрос, он возвращает несколько строк, когда он должен возвращать только 1 строку. Позвольте мне настроить его, так проще объяснить.

  1. Создать тестовую таблицу: CREATE TABLE test_table ( test_val VARCHAR(255) ) ;
  2. Загрузить 3 значения в таблицу: INSERT INTO test_table (test_val) VALUES ('9671986020630615'), ('9671986020630616'), ('9671986020630617') ;
  3. Выполнить этот запрос (этот запрос возвращает 1 ожидаемую строку): SELECT * FROM test_table WHERE test_val = '9671986020630615' ;

  4. Выполнить этот запрос (этот запрос возвращает 3 строки, чего не должно быть): SELECT * FROM test_table WHERE test_val = 9671986020630615 ;

Вот что я наблюдал в этой ситуации:

  1. Первый запрос окружает значение в предложении WHERE одинарными кавычками.
  2. Второй запрос не окружает значение в предложении WHERE одиночными галочками.
  3. Столбец в тестовой таблице определен как VARCHAR(255)
  4. Имеет смысл, что первый запрос возвращает только одну строку, потому что он сравнивает строку из предложения WHERE со значением строки в тестовой таблице (VARCHAR(255))
  5. Что-то происходит, когда MySQL сравнивает числовое значение в предложении WHERE второго запроса со строковым значением в тестовой таблице (VARCHAR(255)), из-за чего MySQL возвращает 3 строки вместо просто 1.

Имеет смысл, что первый запрос возвращает правильный результат, потому что он сравнивает строку со строкой.

Также имеет смысл, что второй запрос возвращает неверный набор данных (3 строки в отличие от 1 строки, которую он должен вернуть).

Но мой вопрос , почему MySQL делает это? Почему, когда он сравнивает число с 3 различными значениями VARCHAR(255), он возвращает все 3 строки, когда истинное значение числового значения в предложении WHERE соответствует только 1 строке?

Итак, по сути, для первого запроса MySQL говорит:

'9671986020630615' = '9671986020630615',

9671986020630615 <9671986020630616, </p>

'9671986020630615' <> '9671986020630617'

но для второго запроса он говорит:

9671986020630615 = '9671986020630615',

9671986020630615 = '9671986020630616',

9671986020630615 = '9671986020630617'

Любая помощь будет высоко ценится.

1 Ответ

5 голосов
/ 06 июня 2019

MySQL внутренне обрабатывает все числа так же, как это делает Javascript, с представлением с плавающей точкой двойной точности IEEE .

Когда вы опускаете кавычки в длинных числовых строках, то есть вы пишете 9671986020630615 вместо '9671986020630615 ', MySQL использует число. Затем, когда он запускает часть запроса WHERE, он автоматически приводит значение каждого столбца к числу с двойной точностью.

Но из-за машины epsilon - предел точности - двойной точности, 9671986020630615, 9671986020630616 и 9671986020630617 имеют одинаковое значение. Итак, ГДЕ находит все три.

CAST(9671986020630615 AS DOUBLE) CAST(9671986020630616 AS DOUBLE) CAST(9671986020630617 AS DOUBLE) 
     9.671986020630616e15             9.671986020630616e15             9.671986020630616e15 | 

Посмотрите, как все три целых числа имеют такое же представление, как DOUBLE?

...