如何在MySQL中按子网分组IP列表?

xu3bshqb  于 2023-02-18  发布在  Mysql
关注(0)|答案(5)|浏览(123)

我需要按子网(前3个八位字节)对IP列表进行分组以进行计数。例如,如果我有IP

123.12.12.12
123.12.12.11
123.12.11.11

我不得不得到这样的结果:

123.12.12 | 2
123.12.11 | 1

我在谷歌上搜索了这个例子:

select 
substr(ip,1,locate('.',ip,locate('.',ip)+1)-1) 
as ip, count(ip) as count
from ip_list
group by ip ORDER BY count  DESC

但是它只按前两个八位字节对列表进行分组。我在所有这些locate(locate(locate(...)))中迷失了方向。有人能帮助修改它以获得正确的结果吗?

insrf1ej

insrf1ej1#

您应该使用group by * 表达式名称 *。

select 
--   locate( '.', ip, locate( '.', ip, locate( '.', ip ) + 1 ) + 1 ) as l,
   substr( ip, 1, locate( '.', ip
                          , locate( '.', ip
                                    , locate( '.', ip ) + 1 ) + 1 ) - 1 ) as subip,
   count(ip) as count
from ip_list
group by ( subip )
order by count desc
;
    • 编辑1**:

不需要使用locateSUBSTR_INDEX可用于过滤IP子集。

    • 示例**:
select
       substring_index( ip, '.', 3 ) as subip
     , count(ip) as count
  from ip_list
 group by ( subip )
 order by count desc
    • 参考文档**:
      • MySQL:SUBSTR(字符串,位置,长度)**
  • 从字符串str返回长度为len个字符的子字符串,从位置pos开始。
      • MySQL:SUBSTRING_INDEX(字符串,分隔符,计数)**
  • 返回字符串str中出现分隔符delim之前的子字符串。
dwthyt8l

dwthyt8l2#

使用这种逻辑,恐怕您需要在那里再添加一层locate

substr(ip, 1, locate('.', ip, locate('.', ip, locate('.', ip)+1) +1) - 1)
y1aodyip

y1aodyip3#

你可以用

GROUP BY INET_ATON(ip)/256
6ss1mwsb

6ss1mwsb4#

如果你把IP地址设为二进制,你可以在它上面加一个掩码,只保留IP地址的前3部分。掩码如下所示:

11111111111111111111111100000000

因此,作为一个数字,它看起来像:

SELECT CONV('11111111111111111111111100000000' ,2,10) as mask;
-- Result: 4294967040

如果您使用此掩码对您的IP地址执行按位AND运算,您将得到如下结果:

SELECT
'1.0.207.199',                
INET_NTOA( INET_ATON( '1.0.207.199') & 4294967040 ) ;
-- Result:
-- 1.0.207.199
-- 1.0.207.0

INET_ATON转换一个IP(A)地址(TO)一个(N)号码,INET_NTOA反之亦然(虽然真正的意思代表ASCII TO网络,但我更喜欢这个shofthand;-).
因此,您可以按IP地址进行分组,如下所示:

SELECT
    INET_NTOA( INET_ATON( ip ) & 4294967040 ) AS ipgroup, 
    COUNT(ip) AS count
FROM ip_list
GROUP BY ipgroup 
ORDER BY count DESC;

希望能有所帮助。

ds97pgxw

ds97pgxw5#

通过以下方式从表格组中选择INET_NTOA((INET_ATON(IP)〉〉X)
X应为32子网
即:选择初始化_非到达时间((初始化_非到达时间('1.1.2.15')〉〉8)〈〈8)

相关问题