Пустой ответ от mysql при правильном запросе
Всем привет, писал код для своего приложения и наткнулся на баг.
Баг заключпется в следующем:
При выполнение данного запроса, то выводится пустой ответ
SELECT * FROM jobs WHERE lat = 47.02489170 AND lng = 28.83106860;
# или
SELECT * FROM jobs WHERE lng = 28.83106860;
Но при выполнение запроса без указывания lng:
SELECT * FROM jobs WHERE lat = 47.02489170;
То выводит следующий ответ:
+------+-----------------------+-------------+-------------+-------------+
| id | title | description | lat | lng |
+------+-----------------------+-------------+-------------+-------------+
| 1510 | Administrator magazin | NULL | 47.02489170 | 28.83106860 |
+------+-----------------------+-------------+-------------+-------------+
Это какой-то баг в mysql или double не настолько точный?
Буду благодарен за любой ответ, или ссылку на статью.
Таблица с вакансиями
CREATE TABLE `jobs` (
`id` bigint NOT NULL AUTO_INCREMENT,
`title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci,
...
`lat` double(10,8) DEFAULT NULL,
`lng` double(10,8) DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=3230 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC
Ответы (3 шт):
Числа с плавающей запятой иногда вызывают путаницу, поскольку они приблизительны и не сохраняются как точные значения. Значение с плавающей запятой, записанное в инструкции SQL, может не совпадать со значением, представленным внутри. Попытки рассматривать значения с плавающей запятой как точные при сравнении могут привести к проблемам. Они также зависят от платформы или реализации. Этим проблемам подвержены типы данных FLOAT
и DOUBLE
. Для столбцов DECIMAL
MySQL выполняет операции с точностью до 65 десятичных цифр, что должно решить наиболее распространенные проблемы с неточностями.
https://dev.mysql.com/doc/refman/8.4/en/floating-point-types.html
Как уже написали, числа с плавающей точкой не могут быть точно представлены. Поэтому, например, вы можете просто найти в базе точку, ближайшую к вашим координатам по евклидову расстоянию:
SELECT * FROM jobs
ORDER BY POW(lat - 47.02489170, 2) + POW(lng - 28.83106860, 2)
LIMIT 1;
Можно добавить в вывод и само это расстояние.