如何在 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
部分。
我有一个 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
部分。