SQL订单字符串作为数字

时间:2012-08-04 12:12:59

标签: mysql sql string numbers sql-order-by

我将数字保存为VARCHAR到MySQL数据库。由于其他一些具体情况,我不能让他们INT

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

在数据库中我有

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

在我的页面上显示如下的有序列表:

1 10 2 3 4 5 6 7 8 9

如何按升序显示数字?

11 个答案:

答案 0 :(得分:212)

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

如果你不能这样做,那么使用

将列值显式地转换为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 */

答案 1 :(得分:58)

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

(对于使用JPA 2.0且不允许进行转换的人)

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

编辑:仅适用于正整数

答案 2 :(得分:15)

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

def tax(bill):
    """Adds 8% tax to a restaurant bill."""
    bill *= 1.08
    print "With tax: %f" % bill
    return bill

def tip(bill):
    """Adds 15% tip to a restaurant bill."""
    bill *= 1.15
    print "With tip: %f" % bill
    return bill

meal_cost = 100
meal_with_tax = tax(meal_cost)
meal_with_tip = tip(meal_with_tax)

结果

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;

希望这有帮助

答案 3 :(得分:7)

另一种简单的方法

{ "_id" : ObjectId("57a5df273c6c00d1378b456d"), "review_time" : ISODate("2016-02-06T12:59:19.000Z"), "review" : "My name is Sandra P. and I am a satisfied customer. I've been working with eBrandz for a little more than two years and plan on keep doing so. They are always there whenever I have any concern and their approach is very professional. I would definitely recommend their services as I have seen great results.", "rating" : 5, "review_reply" : [ { "author" : "http://new york.cylex usa.com/company/ebrandz inc 18441959.html", "reply_time" : "1969-12-31", "reviews" : "Sandra thanks for recommending ebrandz, appreciated." }, { "author" : "http://new york.cylex usa.com/company/ebrandz inc 18441959.html", "reply_time" : "1969-12-31", "reviews" : "Sandra thanks for recommending ebrandz, appreciated.1" }, { "author" : "http://new york.cylex usa.com/company/ebrandz inc 18441959.html", "reply_time" : "1969-12-31", "review" : "Sandra thanks for recommending ebrandz, appreciated22." } ], }

答案 4 :(得分:4)

转换的另一种方式。

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

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

或按照'tensymbols13','tensymbols1222'等字段的顺序排序。

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

答案 5 :(得分:3)

这适合我。

select * from tablename
order by cast(columnname as int) asc

答案 6 :(得分:2)

我还在查找具有字母前缀的排序字段。以下是我发现的解决方案。这可能有助于谁在寻找相同的解决方案。

字段值:

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

答案 7 :(得分:2)

这将处理负数,分数,字符串,所有内容:

ORDER BY ISNUMERIC(col) DESC, Try_Parse(col AS decimal(10,2)), col;

答案 8 :(得分:2)

这可能有助于寻找相同解决方案的人。

select * from tablename ORDER BY ABS(column_name)

答案 9 :(得分:0)

如果您使用的是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

答案 10 :(得分:-3)

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

  

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

然后先确定依赖情况。否则,您正在解决真正的潜在问题。使用MySQL CAST是一个选项,但它掩盖了你应该修复的坏架构。

相关问题