У меня проблема с подзапросом с адресами IPV4, хранящимися в MySQL (MySQL 5.0).Номера IP-адресов в подзапросе MySQL
IP-адреса хранятся в двух таблицах, как в формате сетевого номера - например, формат, выводимый INET_ATON() MySQL. Первая таблица («события») содержит множество строк с связанными с ними IP-адресами, вторая таблица («network_providers») содержит список информации о поставщике для данных сетевых блоков.
событие таблицы (~ 4000000 строк):
event_id (int)
event_name (varchar)
ip_address (unsigned int)
network_providers таблицы (~ 60000 строк):
ip_start (unsigned int)
ip_end (unsigned int)
provider_name (varchar)
Упрощенный для целей проблемы у меня, целью является создание экспорта по следующим направлениям:
event_id,event_name,ip_address,provider_name
Если сделать запрос по линиям либо из следующих, я получаю результат я ожидаю:
SELECT provider_name FROM network_providers WHERE INET_ATON('192.168.0.1') >= network_providers.ip_start ORDER BY network_providers.ip_start DESC LIMIT 1
SELECT provider_name FROM network_providers WHERE 3232235521 >= network_providers.ip_start ORDER BY network_providers.ip_start DESC LIMIT 1
То есть, он возвращает правильный PROVIDER_NAME для любой IP я смотрю вверх (из Конечно, я не использую 192.168.0.1 в своих запросах).
Однако при выполнении этого же запроса в качестве подзапроса, следующим образом, это не дает результат я бы ожидать:
SELECT
events.event_id,
events.event_name,
(SELECT provider_name FROM network_providers
WHERE events.ip_address >= network_providers.ip_start
ORDER BY network_providers.ip_start DESC LIMIT 1) as provider
FROM events
Вместо этого другое (неправильное) значение поставщика возвращается. Более 90% (но любопытно не всех) значений, возвращаемых в столбце , содержат неверную информацию о провайдере для этого IP-адреса.
Использование events.ip_address в подзапросе только для того, чтобы выдать значение подтверждает, что оно содержит значение, которое я ожидаю, и что подзапрос может его проанализировать. Замена events.ip_address с фактическим номером сети также работает, просто используя его динамически в подзапросе таким образом, что не работает для меня.
Я подозреваю, что проблема в том, что есть что-то фундаментальное и важное в отношении подзапросов в MySQL, которые я не получаю. Ранее я работал с IP-адресами, подобными этому в MySQL, но раньше не делал поиска для них, используя подзапрос.
Вопрос:
Я действительно ценю пример того, как я мог бы получить выход, я хочу, и если кто-то здесь знает, некоторое просветление, почему то, что я делаю не работает поэтому я могу избежать повторения этой ошибки.
Примечания:
Фактическое использование в реальном мире, что я пытаюсь сделать, это значительно сложнее (с участием объединения двух или трех таблиц). Это упрощенная версия, чтобы избежать чрезмерного усложнения вопроса.
Кроме того, я знаю, что я не использую между ip_start & ip_end - это намеренно (DB может быть устаревшим, и в таких случаях владелец в базе данных почти всегда находится в следующем указанном диапазоне и «лучше угадайте, в этом контексте хорошо, однако я благодарен за любые предложения по улучшению, которые касаются вопроса.
Эффективность всегда хорошая, но в этом случае абсолютно не обязательно - любая помощь оценивается.
Я думаю, что извращенный Cartesian Product (или его подмножество) появился из-за вашего неявного соединения (возможно, это неправильный термин, но таблицы * здесь соединяются здесь ...) – MvanGeest