我的mySQL数据库中有2个表。
第一个表是isp:
isp_ip_address | isp_name
-------------------------
157.55.33.0 | isp_3
157.55.0.0 | isp_1
193.219.9.0 | isp_2
65.55.213.0 | isp_4
195.182.85.226 | isp_5
78.58.5.117 | isp_6
78.58.5.0 | isp_7
第二个表是user_stats:
uid | lastlogin_ip | lastlogin
------------------------------
111 | 78.58.83.111 | 2013-03-12
132 | 78.58.5.117 | 2013-03-12
258 | 195.182.85.226 | 2013-03-14
165 | 157.55.33.78 | 2013-03-12
822 | 65.55.213.216 | 2013-03-15
523 | 157.55.35.38 | 2013-03-12
.....
等等。
我需要将用户lastlogin_ip与isp_ip_address进行比较 并在新表中插入uid,lastlogin_ip和isp_name。我需要像这样比较ip_address:如果完全lastlogin_ip等于isp_ip_address然后停止搜索并写入isp_name,如果它们不匹配,我需要比较firdt 3部分IP地址并做同样的事情,如果3部分不匹配,我需要比较2部分IP地址并做同样的事情。
我尝试了以下SQL代码:
SELECT
user_stats.`uid`,
user_stats.`lastlogin_ip`,
isp.`isp`,
FROM
stats.`user_stats`
LEFT JOIN stats.`isp`
ON(
IF(
isp.isp_ip_address LIKE user_stats.`lastlogin_ip`,
isp.isp_ip_address LIKE user_stats.`lastlogin_ip`,
IF(
SUBSTRING_INDEX(isp.isp_ip_address,'.',-1) LIKE SUBSTRING_INDEX(user_stats.`lastlogin_ip`,'.',-1),
IF(
SUBSTRING_INDEX(SUBSTRING_INDEX(isp.isp_ip_address,'.',3),'.',-1) LIKE SUBSTRING_INDEX(SUBSTRING_INDEX(user_stats.`lastlogin_ip`,'.',3),'.',-1),
IF(
SUBSTRING_INDEX(SUBSTRING_INDEX(isp.isp_ip_address,'.',2),'.',-1) LIKE SUBSTRING_INDEX(SUBSTRING_INDEX(user_stats.`lastlogin_ip`,'.',2),'.',-1),
SUBSTRING_INDEX(isp.isp_ip_address,'.',1) LIKE SUBSTRING_INDEX(user_stats.`lastlogin_ip`,'.',1),
NULL),
SUBSTRING_INDEX(isp.isp_ip_address,'.',2) LIKE SUBSTRING_INDEX(user_stats.`lastlogin_ip`,'.',2)),
SUBSTRING_INDEX(isp.isp_ip_address,'.',3) LIKE SUBSTRING_INDEX(user_stats.`lastlogin_ip`,'.',3))));
此代码比较部分IP地址,但它复制了行,这意味着如果它找到3个相等的部分和2个相等的部分,它会使用不同的isp_name值将相同的行写入两次。
你能给我一个提示,我应该如何编辑这段代码才能正常工作? 任何帮助将不胜感激!
答案 0 :(得分:0)
您的加入条件与您的说明不符。使用否定计数时,substring_index
会返回ip
的右侧,而不是左侧。
无论如何,请尝试以下加入条件(未经测试):
ON(
isp.isp_ip_address = user_stats.lastlogin_ip
OR SUBSTRING_INDEX(isp.isp_ip_address,'.', 3) = SUBSTRING_INDEX(user_stats.lastlogin_ip,'.', 3)
OR SUBSTRING_INDEX(isp.isp_ip_address,'.', 2) = SUBSTRING_INDEX(user_stats.lastlogin_ip,'.', 2)
)
答案 1 :(得分:0)
将IP地址和CIDR存储为整数不是更好,然后使用以下内容:Is there way to match IP with IP+CIDR straight from SELECT query?
答案 2 :(得分:0)
非常未经测试,但希望能让你走上正轨:
编辑:qry修复了语法并进行了测试。
SELECT match3.lastlogin_ip, ifnull(match3.isp_name, isp.isp_name) as isp_name FROM (SELECT match4.lastlogin_ip, ifnull(match4.isp_name, isp.isp_name) as isp_name, isp.isp_ip_address FROM (SELECT user_stats.lastlogin_ip, isp.isp_name, isp.isp_ip_address FROM user_stats LEFT JOIN isp ON (user_stats.lastlogin_ip = isp.isp_ip_address)) as match4 LEFT JOIN isp ON (match4.isp_name is null and SUBSTRING_INDEX(match4.lastlogin_ip,'.', 3) = SUBSTRING_INDEX(isp.isp_ip_address,'.', 3))) as match3 LEFT JOIN isp ON (match3.isp_name is null and SUBSTRING_INDEX(match3.lastlogin_ip,'.', 2) = SUBSTRING_INDEX(isp.isp_ip_address,'.', 2));