Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL IP地址与ISP共享_Mysql_Sql_If Statement_Ip Address - Fatal编程技术网

MySQL IP地址与ISP共享

MySQL IP地址与ISP共享,mysql,sql,if-statement,ip-address,Mysql,Sql,If Statement,Ip Address,我的mySQL数据库中有两个表 第一个表是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 第二个

我的mySQL数据库中有两个表

第一个表是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
第二个表是用户统计:

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
.....
等等

我需要比较用户最后登录的ip地址和isp的ip地址 并在新表中插入uid、lastlogin\u ip和isp\u名称。我需要这样比较ip地址:如果完整的lastlogin\u ip等于isp\u ip\u地址,则停止搜索并写入isp\u名称,如果它们不匹配,我需要比较ip地址的前三部分并执行相同的操作,如果三部分不匹配,我需要比较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_名称值写入同一行两次

你能给我一个提示吗?我应该如何编辑这段代码才能正常工作?
任何帮助都将不胜感激

您的加入条件与您的描述不符。与负计数一起使用时,子字符串_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)
)

将IP地址和CIDR存储为整数,然后使用以下内容不是更好吗:

阅读这些查询更容易 可能比你现在拥有的要快 就网络而言,比较比子串比较更准确。
非常未经测试,但希望能让您步入正轨:

编辑: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));
此联接条件仍然与行重复。例如,如果我有IP地址78.58.5.117,它将用isp_名称isp_7写入一次,用isp_名称isp_6写入一次,因为有isp_名称->isp_7,其中isp_地址->78.58.5.0三部分相等,isp_名称->isp_6,其中isp_名称->isp_地址->78.58.5.117所有四部分相等。如果78.58.5.117=78.58.5.117或不相等,我只需要插入一次,请尝试比较IP地址78.58.5.%=78.58.5%的前3部分。如果不相等,请尝试比较前2部分78.58.%.%=78.58.%。这不能用单个联接来完成,因为联接一次只比较每个表中的一条记录。在您的情况下,由于子/超级ISP,涉及多个记录。三个组合中的每一个都需要子查询,然后需要部分联接来选择相关记录。如果你需要的话,我稍后会尝试提供一个更完整的答案。如果你能为我提供更完整的答案,那将是太好了,因为我已经不知道如何创建这个查询了。我编辑了你的查询。有一些语法错误,但这个查询只给出ip地址全部4部分相等的行的isp_名称。3个部分、2个部分和其他行为空。这似乎是您要求的:等于所有4个部分。3个部分,2个部分。少了什么?我找不到有什么问题。但是当我运行这个查询时,它只显示ip地址和lastlogin的4个部分都相等的isp_名称。当3个或2个部分相等时,查询不会写入isp_名称,也不会写入NULL值而不是TEADOK。从您的第一条评论中可以看出,isp_名称在2和3个匹配项中为NULL。与isp不匹配的行实际上应该将isp_名称返回为NULL。请用语法正确的SQL编辑我的答案,我会看一看。我已经修复了语法错误,并且仅仅为了可读性的目的修改了一些标准。查询是根据您的解释进行的。请注意,您的示例中的uid=111和uid=523将按预期分别获得两个isp,因为其中可能缺少一些isp记录。