174

我将数字保存为VARCHARMySQL 数据库。INT由于其他一些情况,我无法制作它们。

排序时将它们视为字符而不是数字。

在数据库中我有

1 2 3 4 5 6 7 8 9 10...

在我的页面上,它显示了这样的有序列表:

1 10 2 3 4 5 6 7 8 9

如何使它按数字升序排列?

4

11 回答 11

312

如果可能,如果您只存储数字,则应将列的数据类型更改为数字。

如果你不能这样做,那么将你的列值integer 明确地转换为

select col from yourtable
order by cast(col as unsigned)

隐含地,例如使用强制转换为数字的数学运算

select col from yourtable
order by col + 0

BTW MySQL 从左到右转换字符串。例子:

string value  |  integer value after conversion
--------------+--------------------------------
'1'           |  1
'ABC'         |  0   /* the string does not contain a number, so the result is 0 */
'123miles'    |  123 
'$123'        |  0   /* the left side of the string does not start with a number */
于 2012-08-04T12:15:44.993 回答
83

另一种方式,不使用单个演员表。

(对于使用 JPA 2.0 的人,不允许强制转换)

select col from yourtable
order by length(col),col

编辑:仅适用于正整数

于 2014-07-31T14:12:20.130 回答
28

另一种简单的方法

ORDER BY ABS(column_name)

于 2017-03-10T07:36:13.250 回答
21

我用来排序的列有字母和数字的任意组合,所以我使用这篇文章中的建议作为起点并想出了这个。

DECLARE @tmp TABLE (ID VARCHAR(50));
INSERT INTO @tmp VALUES ('XYZ300');
INSERT INTO @tmp VALUES ('XYZ1002');
INSERT INTO @tmp VALUES ('106');
INSERT INTO @tmp VALUES ('206');
INSERT INTO @tmp VALUES ('1002');
INSERT INTO @tmp VALUES ('J206');
INSERT INTO @tmp VALUES ('J1002');

SELECT ID, (CASE WHEN ISNUMERIC(ID) = 1 THEN 0 ELSE 1 END) IsNum
FROM @tmp
ORDER BY IsNum, LEN(ID), ID;

结果

ID
------------------------
106
206
1002
J206
J1002
XYZ300
XYZ1002

希望这可以帮助

于 2015-10-15T02:41:37.273 回答
8

这对我有用。

select * from tablename
order by cast(columnname as int) asc
于 2018-05-17T09:22:40.870 回答
6

它可能对正在寻找相同解决方案的人有所帮助。

select * from tablename ORDER BY ABS(column_name)
于 2020-02-21T08:01:15.467 回答
5

另一种转换方式。

如果您有字符串字段,则可以通过以下方式对其或其数字部分进行转换:添加前导零以使所有整数字符串具有相等的长度。

ORDER BY CONCAT( REPEAT(  "0", 18 - LENGTH( stringfield ) ) , stringfield ) 

或按字段的一部分排序,例如“tensymbols13”、“tensymbols1222”等。

ORDER BY CONCAT( REPEAT(  "0", 18 - LENGTH( LEFT( stringfield , 10 ) ) ) , LEFT( stringfield , 10 ) ) 
于 2014-05-19T13:48:57.370 回答
4

我也在寻找一个带有字母前缀的排序字段。这是我找到的解决方案。这可能对正在寻找相同解决方案的人有所帮助。

字段值:

FL01,FL02,FL03,FL04,FL05,...FL100,...FL123456789

select SUBSTRING(field,3,9) as field from table order by SUBSTRING(field,3,10)*1 desc

SUBSTRING(field,3,9)我放 9 是因为 9 足以让我保存最多 9 位整数值。

所以结果将是 123456789 123456788 123456787 ... 100 99 ... 2 1

于 2016-02-05T04:22:09.850 回答
4

这将处理负数、分数、字符串,一切:

ORDER BY ISNUMERIC(col) DESC, Try_Parse(col AS decimal(10,2)), col;
于 2018-03-30T23:43:50.810 回答
-1

如果您使用的是 AdonisJS 并且具有混合 ID,例如 ABC-202、ABC-201...,您可以将原始查询与 Query Builder 结合起来并实施上述解决方案 ( https://stackoverflow.com/a/25061144/4040835 )如下:

const sortField =
  'membership_id'
const sortDirection =
  'asc'
const subquery = UserProfile.query()
  .select(
    'user_profiles.id',
    'user_profiles.user_id',
    'user_profiles.membership_id',
    'user_profiles.first_name',
    'user_profiles.middle_name',
    'user_profiles.last_name',
    'user_profiles.mobile_number',
    'countries.citizenship',
    'states.name as state_of_origin',
    'user_profiles.gender',
    'user_profiles.created_at',
    'user_profiles.updated_at'
  )
  .leftJoin(
    'users',
    'user_profiles.user_id',
    'users.id'
  )
  .leftJoin(
    'countries',
    'user_profiles.nationality',
    'countries.id'
  )
  .leftJoin(
    'states',
    'user_profiles.state_of_origin',
    'states.id'
  )
  .orderByRaw(
    `SUBSTRING(:sortField:,3,15)*1 ${sortDirection}`,
    {
      sortField: sortField,
    }
  )
  .paginate(
    page,
    per_page
  )

注意: 在这一行:SUBSTRING(:sortField:,3,15)*1 ${sortDirection}

  1. '3'代表数字前最后一个非数字字符的索引号。如果您的混合 ID 是“ABC-123”,那么您的索引号将为 4。
  2. '15'用于在连字符后捕获尽可能多的数字。
  3. '1'对子字符串执行数学运算,有效地将子字符串转换为数字。

参考 1:您可以在此处阅读有关原始查询中的参数绑定的更多信息:https ://knexjs.org/#Raw-Bindings 参考 2:Adonis 原始查询:https ://adonisjs.com/docs/4.1/query-builder# _raw_queries

于 2020-03-26T20:37:30.580 回答
-4

将您的字段更改为 INT 而不是 VARCHAR。

由于其他一些情况,我无法将它们设为 INT。

然后先解决依赖的情况。否则,您正在解决真正的潜在问题。使用 MySQL CAST 是一种选择,但它掩盖了应该修复的错误模式。

于 2015-11-18T11:34:35.480 回答