MySQL 对 IP 字段的排序问题
MySQL 对 IP 字段的排序问题
问题描述
想对一张带有 IP 字段的表,对 IP 字段进行升序排序,方便查看每个段的 IP 信息。
表结构和表数据如下:
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0; -- ----------------------------
-- Table structure for t_ip
-- ----------------------------
DROP TABLE IF EXISTS `t_ip`;
CREATE TABLE `t_ip` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`ip` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; -- ----------------------------
-- Records of t_ip
-- ----------------------------
INSERT INTO `t_ip` VALUES (1, '192.168.10.8');
INSERT INTO `t_ip` VALUES (2, '192.168.10.9');
INSERT INTO `t_ip` VALUES (3, '192.168.10.10');
INSERT INTO `t_ip` VALUES (4, '192.168.10.1');
INSERT INTO `t_ip` VALUES (5, '192.168.8.8');
INSERT INTO `t_ip` VALUES (6, '192.167.10.8');
INSERT INTO `t_ip` VALUES (7, '192.167.8.8');
INSERT INTO `t_ip` VALUES (8, '92.168.10.8');
INSERT INTO `t_ip` VALUES (9, '92.68.10.8'); SET FOREIGN_KEY_CHECKS = 1;
数据库查询截图如下:

如果按照 IP 字段升序,查询效果如下:

问题原因
由于 IP 字段是varchar 类型,MySQL在进行排序的时候,并不会将 IP中的 “192”和“92” 自动识别为数字进行处理,而是作为字符串处理了。
因此,会查询到的结果达不到预期。
问题解决
如果想要将92开头的IP,排在192开头的之前,并且每个. 分隔的段都要保持数字上的升序,需要对 IP 字段按照 . 进行分解为4段,逐次排序处理。
处理 SQL 如下:
select ip from t_ip
ORDER BY
CONVERT(SUBSTRING_INDEX(ip, '.', 1), SIGNED),
CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(ip, '.', 2), '.', -1), SIGNED),
CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(ip, '.', 3), '.', -1), SIGNED),
CONVERT(SUBSTRING_INDEX(ip, '.', -1), SIGNED);
处理后的效果截图如下(此时已经达到了预期的排序效果):

【说明】
此处用到了MySQL的两个库函数:
1) CONVERT(expr,type): 此函数的作用是将表达式转换为特定类型
如:上面用到的 CONVERT(SUBSTRING_INDEX(ip, '.', 1), SIGNED) 是将ip字段中获取的第一位,转换为整数。
2)SUBSTRING_INDEX(str,delim,count):此函数的作用是将一个字段串,按照某个标识字符串截取,并获取第几个之前
如:SUBSTRING_INDEX(ip, '.', 1) 是将IP按照 '.' 分隔,获取第一位。如果是ip是 192.168.10.8,获取的就是 192
SUBSTRING_INDEX(ip, '.', -1) 是将IP按照 '.' 分隔,获取最后一位。如果是ip是 192.168.10.8,获取的就是 8
额外补充
如果IP字段中存在多IP,如:192.168.10.2,194.16.12.123,要求排序的时候,按照逗号前的第一个IP参与排序。需要如何实现呢?
如果还是按照上面的SQL,发现不能适配该场景,效果如下:

此时,需要对多IP的场景的逗号稍微处理下即可,处理SQL如下:
select ip from t_ip
ORDER BY
CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(ip, ',', 1), '.', 1), SIGNED),
CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(ip, ',', 1), '.', 2), '.', -1), SIGNED),
CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(ip, ',', 1), '.', 3), '.', -1), SIGNED),
CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(ip, ',', 1), '.', -1), SIGNED);
该SQL的查询效果如下:

MySQL 对 IP 字段的排序问题的更多相关文章
- Mysql hql字符串字段中是否包含某个字符串,用 find_in_set
有这样一个需求,在Mysql数据库字符串字段(权限)中,有范围在 1 到 N 之间代表不同权限的值,分别被','分开,现在要取出具有某权限的所有成员列表. 创建表: 1 CREATE TABLE us ...
- MySQL 表与字段编码格式报错
MySQL 表与字段编码格式报错 一.数据库,表,字段编码格式都为latin1(iso-8859-1) .当数据保存到数据库后,中文显示乱码. 解决办法: 1.在访问数据库连接串中添加编码格式: &l ...
- paip.解决 数据库mysql增加列 字段很慢添加字段很慢
paip.解决 数据库mysql增加列 字段很慢添加字段很慢 #环境如下: mysql5.6 数据仅仅3w alter table xxx add column yyy int default ...
- MYSQL的分区字段,必须包含在主键字段内
MYSQL的分区字段,必须包含在主键字段内 MYSQL的分区字段,必须包含在主键字段内 在对表进行分区时,如果分区字段没有包含在主键字段内,如表A的主键为ID,分区字段为createtime ,按 ...
- mysql中判断字段为空
mysql中判断字段为null或者不为null 在mysql中,查询某字段为空时,切记不可用 = null, 而是 is null,不为空则是 is not null select nulco ...
- MySQL根据某个字段查询重复的数据
select count(*) '个数',mobile '手机号',`name` '用户名' from users group by mobile having(count(*) > 1); = ...
- Sender IP字段为"0.0.0.0"的ARP请求报文
今天在研究免费ARP的过程中,抓到了一种Sender IP字段为“0.0.0.0”的ARP请求报文(广播),抓包截图如下: 这让我很疑惑.一个正常的ARP请求不应该只是Target MAC字段为全0吗 ...
- awk中截取IP字段
由于文本的特殊性,IP字段可能并不是在特定的字段中. 借助awk的match()函数进行匹配截取 awk --re-interval '($0 ~ "xxx"){match($0, ...
- 【mysql】IP地址整数int和varchar的转换
mysql中IP地址的存储 IP:如192.168.12.145,在存储时,若是采用varchar进行存储,存在两个主要缺点: 存储空间占用较大: 查询检索较慢: 解决方式: 存储时:将字符串类型的I ...
随机推荐
- java 如何读取src根目录下的属性文件
在java项目中,如何获取src根目录下的属性文件/资源文件呢? 有如下三种方式: 方式一: InputStream in = Test.class .getResourceAsStream(&quo ...
- js去掉url后某参数【函数封装】
function delParam(paramKey) { var url = window.location.href; //页面url var urlParam = window.location ...
- Summer training #7
B:读懂题意模拟 #include <bits/stdc++.h> #include <cstring> #include <iostream> #include ...
- 查看 SharePoint Server 中的所有网站集
网站集是具有同一所有者并共享管理设置(例如权限和配额)的一组网站.网站集是在 Web 应用程序中创建的.创建网站集时,将自动在网站集中创建一个首要网站.然后,可以在首要网站下创建一个或多个子网站.首要 ...
- HDU-4513-完美队形2(Manacher变形)
链接: http://acm.hdu.edu.cn/showproblem.php?pid=4513 题意: 吉哥又想出了一个新的完美队形游戏! 假设有n个人按顺序站在他的面前,他们的身高分别是h[1 ...
- MVN 报错1
找不到mapper映射文件 只打包了下面这些 所以pom.xml文件中添加 <!-- 如果不添加此节点mybatis的mapper.xml文件都会被漏掉. --> <build> ...
- 关于java代理(静态代理和动态代理)
参考文章:http://kuangbaoxu.iteye.com/blog/193240
- 1012 最大公约数和最小公倍数问题 2001年NOIP全国联赛普及组
1012 最大公约数和最小公倍数问题 2001年NOIP全国联赛普及组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 白银 Silver 题目描述 Description 输入二个 ...
- cogs1355. 读书
1355. 读书 ★ 输入文件:reading.in 输出文件:reading.out 简单对比时间限制:1 s 内存限制:128 MB [题目描述] 放暑假了,CHH想趁假期提高一下 ...
- 线性素数筛(欧拉筛)(超级好的MuBan)
Problem:找出小于等于n的所有素数的个数. #include <bits/stdc++.h> using namespace std; const int maxn = 1e6; i ...