2016-05-24 27 views
0

我想創建一個MySQL查詢來查找子網表中存在的最長匹配(四點格式的給定IP地址)。MySQL LEAST()具有任意數量的參數;在表中最長匹配

最終,我想創建一個LEFT JOIN,它將在一個表中顯示每個四角點IP地址,並與另一個表中的最長匹配進行連接。我不想創建任何臨時表或將其組織爲嵌套查詢。

我有點MySQL的新手,但我在想什麼是這樣的:

SELECT `ip_address` 
    LEFT JOIN ON 
    SELECT `subnet_id` 
    FROM `subnets_table` 
    WHERE (`maximum_ip_value` - `minimum_ip_value`) = 
    LEAST(<list of subnet intervals>) 
     WHERE INET_ATON(<given ip address>) > `minimum_ip_value` 
     AND INET_ATON(<given ip address>) < `maximum_ip_value`; 

這樣minimum_ip_valuemaximum_ip_value是最低和最高十進制格式的IP在一個給定的地址可能subnet--例如,子網172.16.0.0/16:

minimum_ip_value = 2886729728 (or 172.16.0.0) 
maximum_ip_value = 2886795263 (or 172.16.255.255) 

而且<list of subnet intervals>包含subnets_table所有間隔,其中<given ip address>minimum_ip_value和之間

並且如果不止一個區間包含<given ip address>,則加入最小間隔(即,最小子網或最具體和「最長」匹配)。

最終,我真正想要的是與該間隔相對應的subnet_id值。

所以我的問題是:

1)我能用最少的()函數的參數的任意數目?我想比較subnets_table的每一行,或者更具體地說,每行的間隔爲minimum_ip_valuemaximum_ip_value,並選擇最小間隔。

2)我可以在LEFT JOIN查詢中執行所有這些計算嗎?我沒有任何建議,可以快速,封裝,並避免重複查詢相同的數據。

我想知道這是否甚至可以在單個查詢中執行(即不查詢每個ip地址的子網表),但我不知道足以排除。請告知如果這看起來不起作用,所以我可以嘗試另一個角度。

謝謝。

+0

請將您的標籤限制爲您正在使用的RDBMS。對於同樣的問題,MySQL和SQL Server通常需要不同的解決方案。 –

回答

0

一些研究和試驗&錯誤後,我看到有上面的原型查詢的幾個問題:

LEAST()功能只需要的參數的定數。按照我最初的問題,我想要一個可以在任意數量的參數或表中的每一行上工作的函數。這在MySQL中是一個不同的功能,MIN()

功能MIN()具有比在MySQL中JOIN功能的優先級低,且在任何給定的查詢中的JOIN功能後進行評價。因此,我不能JOIN在一組值的MIN(),因爲在執行JOINMIN()尚不存在。

我可以看到解決這個問題的唯一方法是執行兩個單獨的查詢:第一個執行MIN(),第一個執行另一個,JOIN執行第一個查詢的結果。這意味着,對於ň行的表,我會執行ň^ñ查詢,而不是ñ查詢。這是不可接受的。

要解決此問題,我編寫了一個新腳本,在執行任何這些查詢之前修改數據庫。每個子網都有自己的「桶」ip值,該範圍內的所有值映射到該子網。如果一個更具體的(即較小的)子網與較不特定的(即更大的)子網重疊,則更具體的範圍只映射到較小的子網,而較大的子網僅保留來自較不具體範圍的值。現在,任何給定的IP地址都只落入一個「桶」中,並映射到只有一個子網,這是其最具體的匹配。我可以JOIN在這場比賽,並且永遠不用擔心MIN()功能。

相關問題