SQL用于按数字排序-1,2,3,4等,而不是1,10,11,12


86

我正在尝试按数据库中数值为1-999的数字列进行排序

当我使用

ORDER_BY registration_no ASC

我明白了。

1
101
102
103
104
105
106
107
108
109
11
110
Etc…

因此,它似乎是按与数字相反的第一个数字排序的。

如果我想按值排序,谁知道使用什么SQL?所以,1,2,3,4,5,6


11
您的列属于varchar类型,因此您正面临此行为。
Meherzad

registration_no列的数据类型是什么?
Praveen Prasannan

9
使用order by registration_no + 0 asc为您解决问题。
Meherzad

10
永远不要将数字存储在字符列中。您的问题是该错误的直接结果。
a_horse_with_no_name

我的列是Varchar,存储的数据是Class 10 / Class 9 / Class8。现在,Class 10在Class 8之前。我如何解决这个问题而不必对display_order列进行处理?
Vishnoo Rath

Answers:


139

当将正整数存储为时,按正整数排序的一种方法是先按varchar长度排序,然后按值排序:

order by len(registration_no), registration_no

当列中可能包含非数字值时,这特别有用。

注:在一些数据库,功能得到一个字符串的长度可能被称为length()替代len()


1
这并非在所有情况下都有效。从头顶上看,无效的案例是整数的混合;负数,带前导零的数字,带分数的数字以及单词和数字的组合。
WonderWorker

10
@ Knickerless-Noggins。。。阅读答案的第一句话。我认为这很清楚。
Gordon Linoff

@GordonLinoff按同一列两次排序是不是CPU和内存密集型?
loneStar

@Achyuth。。。键的数量order by对性能几乎没有影响。
Gordon Linoff

1
对于Oracle SQL,使用length()代替len()
Stevoisiak

61
ORDER_BY cast(registration_no as unsigned) ASC

将值显式转换为数字。实现此目的的另一种可能性是

ORDER_BY registration_no + 0 ASC

这将强制进行隐式对话。

实际上,您应该检查表定义并进行更改。您可以将数据类型更改为int这样

ALTER TABLE your_table MODIFY COLUMN registration_no int;

13

如果您使用的是SQL Server:

ORDER_BY cast(registration_no as int) ASC

3
ORDER_BY cast(registration_no as unsigned) ASC

给出警告的预期结果。

因此,最好去

ORDER_BY registration_no + 0 ASC

没有任何SQL警告的干净结果。


2

我假设您的列类型为STRING(CHAR,VARCHAR等),并且排序过程将其作为字符串进行排序。您需要做的是将值转换为数值。如何执行将取决于您使用的SQL系统。


1

有时,您只是不得不存储与文本混合的数字而已。在我们的一个应用程序中,我们用于电子商务站点的网站托管使过滤器动态地不在列表中。除了显示的文本外,没有其他选项可以按任何字段排序。当我们希望过滤器建立一个表示2“至8” 9“至12” 13“至15”等的列表时,我们需要将其排序为2-9-13,而不是13-2-9读取数值。因此,我将SQL Server复制函数与最长数字的长度一起使用,以用前导空格填充任何较短的数字。现在20在3之后排序,依此类推。

我正在使用一个视图,该视图为我提供了项目类型和类的最小和最大长度,宽度等,这是我如何编写文本的示例。(LB n低和LB n高是5个长度档的低端和高端。)

REPLICATE(' ', LEN(LB5Low) - LEN(LB1High)) + CONVERT(NVARCHAR(4), LB1High) + '" and Under' AS L1Text,
REPLICATE(' ', LEN(LB5Low) - LEN(LB2Low)) + CONVERT(NVARCHAR(4), LB2Low) + '" to ' + CONVERT(NVARCHAR(4), LB2High) + '"' AS L2Text,
REPLICATE(' ', LEN(LB5Low) - LEN(LB3Low)) + CONVERT(NVARCHAR(4), LB3Low) + '" to ' + CONVERT(NVARCHAR(4), LB3High) + '"' AS L3Text,
REPLICATE(' ', LEN(LB5Low) - LEN(LB4Low)) + CONVERT(NVARCHAR(4), LB4Low) + '" to ' + CONVERT(NVARCHAR(4), LB4High) + '"' AS L4Text,
CONVERT(NVARCHAR(4), LB5Low) + '" and Over' AS L5Text

1

我更喜欢对数据执行“ PAD”。MySql称它为LPAD,但是您可以在SQL Server中解决该问题。

ORDER BY  REPLACE(STR(ColName, 3), SPACE(1), '0') 

该公式将基于Column的长度3提供前导零。此功能在ORDER BY以外的其他情况下非常有用,因此这就是我要提供此选项的原因。

结果:1变为001,10变为010,而100保持不变。


0

此问题仅是因为您已在CHAR,VARCHAR或TEXT数据类型中声明了该列。只需将数据类型更改为INT,BIGINT等即可。这将解决您的自定义排序问题。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.