如何在 MySQL 中找到相似的 IP?

How to find similar IPs in MySQL?

我有一个 table,其中包含用户的最后一个 IP。使用以下查询,我能够找到所有重复的 IP 地址

SELECT id, ip, COUNT(ip) AS ip_count FROM users GROUP BY ip HAVING ip_count > 1

我正在尝试 select 仅最后一部分不同的 IP。以下是一些示例:

+--------------+---------------+---------+
|     IP 1     |     IP 2      | Similar |
+--------------+---------------+---------+
| 230.15.26.79 | 230.15.26.230 | true    |
| 32.82.0.5    | 32.82.0.180   | true    |
| 230.15.26.79 | 193.230.15.26 | false   |
| 230.15.26.79 | 230.15.39.115 | false   |
+--------------+---------------+---------+

我可以使用以下命令手动查找是否有与某个特定 IP 相似的 IP:

SELECT id, ip FROM users where ip LIKE "230.15.26.%"

然而,这将意味着我必须循环整个数据库,这是相当庞大的。

是否有另一种方法可以仅通过一到两个查询来执行上述操作?

您可以使用类似于以下的查询来提取所需数据:

SELECT SUBSTRING_INDEX( ip, '.', 3), COUNT(*)  
FROM ipadd
GROUP BY SUBSTRING_INDEX( ip, '.', 3)
HAVING COUNT(*) > 1

假设 table 行中的结构

create table ipadd(id INT, ip VARCHAR(15));

你可以看到它的实际效果here

MySQL 8 Window Functions and Common Table Expressions 也有一个解决方法。也许它会比平时快 GROUP BY 但需要检查:

WITH tmp AS (
    SELECT *, COUNT( * ) OVER ( PARTITION BY SUBSTRING_INDEX( ip, '.', 3 ) ) AS three_parts_of_this_ip_are_similar_in_N_ips FROM user_ips 
)
SELECT * 
FROM tmp 
WHERE three_parts_of_this_ip_are_similar_in_N_ips > 1

假设table和数据:

DROP TABLE IF EXISTS user_ips;
CREATE TABLE user_ips ( user_id INT, ip VARCHAR ( 15 ) );
INSERT INTO user_ips ( user_id, ip )
VALUES
    ( 1, '230.15.26.79' ),
    ( 1, '32.82.0.5' ),
    ( 1, '230.15.26.230' ),
    ( 1, '32.82.0.180' ),
    ( 1, '193.230.15.26' ),
    ( 1, '230.15.39.115' );

你可以看到一个演示 here

如果您需要对每个用户进行计数,只需将用户字段添加到 PARTITION BY 部分。