ORDER BY ASC在包含数字

时间:2016-07-07 10:16:23

标签: mysql sql

我使用MySQL Workbench作为IDE来创建表格。我创建了一个存储过程来显示level列的所有行,并尝试按升序对结果集进行排序。 level列是varchar列。

CREATE DEFINER=`root`@`localhost` PROCEDURE `getAllYearLevels`()
BEGIN
    SELECT `level` FROM yearlevel ORDER BY `level` ASC;
END

但是当我对getAllYearLevels过程执行CALL时,它会返回10级作为第二行而不是2级的结果。

call enrollmentdb.getAllYearLevels();

enter image description here

我知道这对大多数人来说非常简单但我不知道如何纠正这个问题。我使用正确的语法来排序结果集。我想可能需要投射varchar值,但我不知道如何分开它。或许,铸造不是必要的。

我很感激任何帮助。

感谢。

4 个答案:

答案 0 :(得分:1)

我建议更改级别以仅包含数字并添加文本"等级"结果。然后在新数字列上排序将为您提供所需的订单。

答案 1 :(得分:1)

根据您的数据,最简单的方法可能是首先按长度排序,然后按值排序:

ORDER BY LENGTH(`level`), `level

答案 2 :(得分:1)

这里有一些使用SUBSTRING_INDEX和VIRTUAL COLUMN的样本

示例:显示小表的已排序行

MariaDB [yourschema]> SELECT * FROM l ORDER BY substring_index(LEVEL,' ',-1)+0;
+----+----------+
| id | level    |
+----+----------+
|  1 | Grade 1  |
|  3 | Grade 2  |
|  2 | Grade 10 |
+----+----------+
3 rows in set (0.04 sec)

显示表格结构

MariaDB [yourschema]> show create table l;
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                                       |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| l     | CREATE TABLE `l` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `level` varchar(32) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

添加虚拟持久列:

MariaDB [yourschema]> ALTER TABLE l ADD level_int INT AS (SUBSTRING_INDEX(`level`,' ',-1)) PERSISTENT;
Query OK, 3 rows affected (1.90 sec)
Records: 3  Duplicates: 0  Warnings: 0

添加新行:

MariaDB [yourschema]> insert into l (level) VALUES ('Grade 23'),('Grade 132');
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

显示所有行,并查看字段level_int

MariaDB [yourschema]> SELECT * FROM l ORDER BY substring_index(LEVEL,' ',-1)+0;
+----+-----------+-----------+
| id | level     | level_int |
+----+-----------+-----------+
|  1 | Grade 1   |         1 |
|  3 | Grade 2   |         2 |
|  2 | Grade 10  |        10 |
|  4 | Grade 23  |        23 |
|  5 | Grade 132 |       132 |
+----+-----------+-----------+
5 rows in set (0.00 sec)

现在,您可以在新列上添加索引和查询:

MariaDB [yourschema]> alter table l add index idx_level_int (level_int);
Query OK, 5 rows affected (0.93 sec)
Records: 5  Duplicates: 0  Warnings: 0

MariaDB [yourschema]>

答案 3 :(得分:1)

架构设计缺陷......不要存储" 1级"在字符串列中,存储" 1"在数字列中。显示时,前面加上"等级"如果需要的话。