0

我的 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部分不匹配,我需要比较IP地址的2部分并做同样的事情。

我尝试了以下 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 值写入同一行两次。

您能否给我一个提示,我应该如何编辑此代码以使其正常工作?任何帮助,将不胜感激!

4

3 回答 3

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)
)
于 2013-03-25T10:17:57.027 回答
0

非常未经测试,但希望能让你走上正轨:

编辑:qry 已修复语法并经过测试。

选择 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
  (从 user_stats 中选择 user_stats.lastlogin_ip、isp.isp_name、isp.isp_ip_address
  LEFT JOIN isp ON (user_stats.lastlogin_ip = isp.isp_ip_address)) 作为 match4
  LEFT JOIN isp ON (match4.isp_name 为 null 并且 SUBSTRING_INDEX(match4.lastlogin_ip,'.', 3) = SUBSTRING_INDEX(isp.isp_ip_address,'.', 3))) 作为 match3
LEFT JOIN isp ON (match3.isp_name 为空并且 SUBSTRING_INDEX(match3.lastlogin_ip,'.', 2) = SUBSTRING_INDEX(isp.isp_ip_address,'.', 2));
于 2013-03-25T14:03:11.433 回答
0

将 IP 地址和 CIDR 存储为整数然后使用类似这样的东西不是更好吗:有没有办法直接从 SELECT 查询中将 IP 与 IP+CIDR​​ 匹配?

  1. 阅读这些查询更容易
  2. 可能比你现在拥有的更快
  3. 比较比子字符串比较更准确(在网络方面)。
于 2013-03-25T10:37:09.810 回答