У меня проблема с подзапросом, включающим адреса IPV4, хранящиеся в MySQL (MySQL 5.0).
IP-адреса хранятся в двух таблицах, обе в формате номера сети - например, формат вывода MySQL INET_ATON (). Первая таблица ('events') содержит множество строк с ассоциированными с ними IP-адресами, вторая таблица ('network_providers') содержит список информации о провайдере для данных сетевых блоков.
события таблица (~ 4 000 000 строк):
event_id (int)
event_name (varchar)
ip_address (unsigned int)
network_providers таблица (~ 60 000 строк):
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
То есть, он возвращает правильное имя_поставщика для любого 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% (но, как ни странно, не все) значений, возвращаемых в столбце provider , содержат неверную информацию о поставщике для этого IP-адреса.
Использование events.ip_address в подзапросе только для вывода значения подтверждает, что оно содержит ожидаемое значение и что подзапрос может его проанализировать. Замена events.ip_address на фактический номер сети также работает, просто динамически используя его в подзапросе таким способом, который мне не подходит.
Я подозреваю, что проблема заключается в том, что в подзапросах MySQL есть что-то фундаментальное и важное, чего я не понимаю. Я немного раньше работал с такими IP-адресами в MySQL, но ранее не выполнял их поиск с помощью подзапроса.
Вопрос:
Я был бы очень признателен за пример того, как я мог получить желаемый результат, и если кто-то здесь знает, некоторое понимание того, почему то, что я делаю, не работает, поэтому я могу избежать повторения этой ошибки.
Примечания:
Реальное использование в реальных условиях, которое я пытаюсь сделать, значительно сложнее (включая объединение двух или трех таблиц). Это упрощенная версия, чтобы не усложнять вопрос.
Кроме того, я знаю, что я не использую промежуточные значения для ip_start и ip_end - это преднамеренно (базы данных могут быть устаревшими, и в таких случаях владелец базы данных почти всегда находится в следующем указанном диапазоне и 'лучшая догадка «хорошо в этом контексте), однако я благодарен за любые предложения по улучшению, которые касаются вопроса.
Эффективность всегда хороша, но в этом случае абсолютно не важна - любая помощь приветствуется.