MySQL中的带字母数字排序

MySQL中的带字母数字排序

在MySQL中,我们常常需要对包含字母和数字的数据进行排序。比如,在一个包含订单号的表格中,订单号可能为字母和数字的组合,如“ORD001”,“ORD002”,“ORD003”,“ORD01A”,“ORD01B”, “ORD02A”,“ORD02B”,“ORD100”。如何实现按照这种含有数字和字母的顺序排序,使得输出结果满足我们的需求呢?

阅读更多:MySQL 教程

MySQL的默认排序规则

MySQL的默认排序规则是按照字典顺序进行排序。字典顺序是指如果两个字符串从左到右逐个字符比较,第一个不同的字符的ascii码较小的那个字符串排在前面。比如,字符串“a”排在“b”前面,“0”排在“1”前面。

举个例子:

SELECT column1 FROM table1 ORDER BY column1;

上面这个语句会按照column1这个列的内容,按照字典顺序进行排序。如果column1这个列的内容全是数字,那么按照数字大小排序就不是问题。但是,如果column1这个列的内容含有字母,那么就会出现问题。

比如,有如下数据:

column1
2
a
10
b

进行默认排序后,输出结果如下:

column1
10
2
a
b

可以看到,这个排序结果和我们想要的不一样。因为MySQL会先比较字母,再比较数字。所以先输出了“10”,再输出“2”,“a”,“b”。

使用函数实现按照字母数字排序

为了实现按照字母数字排序,我们可以使用MySQL提供的一个函数。该函数是一个自定义的函数,需要借助第三方库实现。这个函数叫做“natural sorting”。它能够按照包含字母和数字的字符串的顺序进行排序。

我们在这里使用的是php的一个库叫做“natsort”。

CREATE FUNCTION `natural_sort`(s1 varchar(200), s2 varchar(200))
RETURNS int
NO SQL
BEGIN
    DECLARE s1_num varchar(200);
    DECLARE s2_num varchar(200);
    DECLARE s1_str varchar(200);
    DECLARE s2_str varchar(200);
    DECLARE s1_ptr int;
    DECLARE s2_ptr int;

    SET s1_ptr=1;
    SET s2_ptr=1;

    WHILE s1_ptr<=length(s1) AND s2_ptr<=length(s2) DO
        SET s1_num="";
        SET s2_num="";

        WHILE s1_ptr<=length(s1) AND substring(s1, s1_ptr, 1) >= '0' AND substring(s1, s1_ptr, 1) <= '9' DO
            SET s1_num=concat(s1_num, substring(s1, s1_ptr, 1));
            SET s1_ptr=s1_ptr+1;
        END WHILE;

        WHILE s2_ptr<=length(s2) AND substring(s2, s2_ptr, 1) >= '0' AND substring(s2, s2_ptr, 1) <= '9' DO
            SET s2_num=concat(s2_num, substring(s2, s2_ptr, 1));
            SET s2_ptr=s2_ptr+1;
        END WHILE;

        IF length(s1_num)>0 AND length(s2_num)>0 THEN
            SET s1_num=cast(s1_num as unsigned);
            SET s2_num=cast(s2_num as unsigned);

            IF s1_num<s2_num THEN
                RETURN -1;
            ELSEIF s1_num>s2_num THEN
                RETURN 1;
            ELSE
                SET s1_ptr=s1_ptr+1;
                SET s2_ptr=s2_ptr+1;         
            END IF;
        ELSEIF length(s1_num)>0 THEN
            RETURN -1;
        ELSEIF length(s2_num)>0 THEN
            RETURN 1;
        ELSE
            SET s1_str=substring(s1, s1_ptr, 1);
            SET s2_str=substring(s2, s2_ptr, 1);

            IF s1_str<s2_str THEN
                RETURN -1;
            ELSEIF s1_str>s2_str THEN
                RETURN 1;
            ELSE
                SET s1_ptr=s1_ptr+1;
                SET s2_ptr=s2_ptr+1;         
            END IF;
        END IF;
    END WHILE;

    IF s1_ptr<=length(s1) THEN
        RETURN 1;
    ELSEIF s2_ptr<=length(s2) THEN
        RETURN -1;
    ELSE
        RETURN 0;
    END IF;
END

创建完成之后,我们可以对上面的例子进行排序:

SELECT column1 FROM table1 ORDER BY natural_sort(column1);

这个语句会输出以下结果:

column1
2
10
a
b

可以看到,这次按照我们的预期进行了排序。

结论

MySQL默认的排序规则只是按照字典顺序进行排序,如果需要按照字母数字的顺序进行排序,则需要使用自定义函数来实现。在实现自定义函数时,我们可以利用php的“natsort”库,通过判断字符串中的数字和字母来实现按照字母数字顺序排序的目的。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程

MySQL 教程