SQL-leetcode—3451. 查找无效的 IP 地址
3451. 查找无效的 IP 地址
表:logs
±------------±--------+
| Column Name | Type |
±------------±--------+
| log_id | int |
| ip | varchar |
| status_code | int |
±------------±--------+
log_id 是这张表的唯一主键。
每一行包含服务器访问日志信息,包括 IP 地址和 HTTP 状态码。
编写一个解决方案来查找 无效的 IP 地址。一个 IPv4 地址如果满足以下任何条件之一,则无效:
任何 8 位字节中包含大于 255 的数字
任何 8 位字节中含有 前导零(如 01.02.03.04)
少于或多于 4 个 8 位字节
返回结果表分别以 invalid_count,ip 降序 排序。
结果格式如下所示。
示例:
输入:
logs 表:
±-------±--------------±------------+
| log_id | ip | status_code |
±-------±--------------±------------+
| 1 | 192.168.1.1 | 200 |
| 2 | 256.1.2.3 | 404 |
| 3 | 192.168.001.1 | 200 |
| 4 | 192.168.1.1 | 200 |
| 5 | 192.168.1 | 500 |
| 6 | 256.1.2.3 | 404 |
| 7 | 192.168.001.1 | 200 |
±-------±--------------±------------+
输出:
±--------------±-------------+
| ip | invalid_count|
±--------------±-------------+
| 256.1.2.3 | 2 |
| 192.168.001.1 | 2 |
| 192.168.1 | 1 |
±--------------±-------------+
解释:
256.1.2.3 是无效的,因为 256 > 255
192.168.001.1 是无效的,因为有前导零
192.168.1 是非法的,因为只有 3 个 8 位字节
输出表分别以 invalid_count,ip 降序排序。
题解
先判断 ip 是不是四段的,使用 LENGTH(ip) - LENGTH(REPLACE(ip, ‘.’, ‘’)) + 1 != 4
使用 SUBSTRING_INDEX 嵌套,分割出 ip 的每个段
转换数据类型,可通过 + 0 转换成数值类型,判断是否大于 255
通过 RLIKE 正则表达式判断是不是 0 开头,如果是 0 , ^0[0-9]+ 表示前导 0 后面还有至少一个数字
方法一 拆解判断
SELECTip,COUNT(*) AS invalid_count
FROM logs
WHERELENGTH(ip) - LENGTH(REPLACE(ip, '.', '')) + 1 != 4 ORSUBSTRING_INDEX(ip, '.', 1) + 0 > 255 OR SUBSTRING_INDEX(ip, '.', 1) RLIKE '^0[0-9]+'OR SUBSTRING_INDEX(SUBSTRING_INDEX(ip, '.', 2), '.', -1) + 0 > 255 OR SUBSTRING_INDEX(SUBSTRING_INDEX(ip, '.', 2), '.', -1) RLIKE '^0[0-9]+'OR SUBSTRING_INDEX(SUBSTRING_INDEX(ip, '.', 3), '.', -1) + 0 > 255 OR SUBSTRING_INDEX(SUBSTRING_INDEX(ip, '.', 3), '.', -1) RLIKE '^0[0-9]+'OR SUBSTRING_INDEX(ip, '.', -1) + 0 > 255 OR SUBSTRING_INDEX(ip, '.', -1) RLIKE '^0[0-9]+'
GROUP BY ip
ORDER BY invalid_count DESC, ip DESC
方法二 正则
select t.ip,count(1) invalid_countfrom logs twhere concat(t.ip,'.') not regexp-- 1-9 | 10-99 | 100-199 | 200-249 | 250-255'^(([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){4}$'group by t.iporder by invalid_count desc,t.ip desc