我有一個涉及存儲在MySQL(MySQL 5.0)中的IPV4地址的子查詢問題。MySQL子查詢中的IP地址編號
IP地址存儲在兩個表格中,都是網絡號碼格式 - 例如,由MySQL的INET_ATON()輸出的格式。第一個表('events')包含許多與IP地址相關聯的行,第二個表('network_providers')包含給定網絡塊的提供者信息列表。
事件表(〜400萬行):
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中的子查詢的基本和重要的東西,我沒有得到。我之前在MySQL中使用過類似IP的地址,但之前沒有使用子查詢對它們進行查詢。
問題:
我會很感激的,我怎麼能得到我想要的輸出的例子,如果有人知道這裏,有所悟,爲什麼我在做什麼不工作所以我可以避免再犯這個錯誤。
注:
實際的現實使用我試圖做的是要複雜得多(包括連接兩個或三個表)。這是一個簡化版本,以避免過分複雜的問題。另外,我知道我沒有在ip_start &之間使用ip_end - 這是故意的(數據庫可能過時了,這種情況下,數據庫中的所有者幾乎總是在下一個指定的範圍內,並且'最好的猜測'在這種情況下是好的),但是我很感激任何與問題有關的改進建議。
效率總是很好,但在這種情況下絕對不是必需的 - 任何幫助表示讚賞。
我認爲由於你的隱式連接(也許這是錯誤的術語,但表* *在這裏被加入......),所以彈出的笛卡兒積(或其子集)已經彈出 – MvanGeest 2010-06-17 14:16:27