想對一張帶有 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;
數據庫查詢截圖以下:spa
若是按照 IP 字段升序,查詢效果以下:code
因爲 IP 字段是varchar 類型,MySQL在進行排序的時候,並不會將 IP中的 「192」和「92」 自動識別爲數字進行處理,而是做爲字符串處理了。blog
所以,會查詢到的結果達不到預期。排序
若是想要將92開頭的IP,排在192開頭的以前,而且每一個. 分隔的段都要保持數字上的升序,須要對 IP 字段按照 . 進行分解爲4段,逐次排序處理。ip
處理 SQL 以下:ci
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的查詢效果以下: