文章介绍了在自己利用普通排序对数据进行排序时发现varchar字符串排序无法得到我们想要的结果,下面我们来介绍利用 case或convert来解决这个问题.
是今天在后台发现排序有问题,于是,没办法,改之,下面简单说一下MySQL的varchar排序问题,引以为戒.
示例表结构,先来看一下,我的表结构:
- showcreatetablecardserverG
- ***************************1.row***************************
- Table:cardserver
- CreateTable:CREATETABLE`cardserver`(
- `id`int(11)NOTNULLdefault'0',
- `ver`int(11)defaultNULL,
- `createtime`datetimedefaultNULL,
- `updatetime`datetimedefaultNULL,
- `game_id`int(2)NOTNULLdefault'0',
- `server_id`varchar(2)NOTNULLdefault'',
- `server_name`varchar(40)NOTNULLdefault'',
- PRIMARYKEY(`id`),
- UNIQUEKEY`game_id_server_id`(`game_id`,`server_id`),
- UNIQUEKEY`game_id_server_name`(`game_id`,`server_name`)
- )ENGINE=InnoDBDEFAULTCHARSET=gbk
- --phpfensi.com
- 1rowinset(0.00sec)
因为有外键的存在,所以我不想改变字段类型,费劲啊,呵呵,虽然最后我还是选择了更改字段类型,这是后话,因为我本篇日志想要说明的是varchar排序问题,所以不再说明我是如何更改字段类型的,大家有兴趣可以搜索我以前的日志.
现象描述:下面,我从数据库里面以server_id排一下序,大家来看一下排序后的结果,代码如下:
- selectserver_idfromcardserverwheregame_id=1orderbyserver_iddesclimit10;
- +-----------+
- |server_id|
- +-----------+
- |8|
- |7|
- |6|
- |5|
- |4|
- |3|
- |2|
- |10|
- |1|
- +-----------+
很明显,我想要的结果应该是 10,8,7,6,5 这样的,但是这个10排在了2的后面,按照字符串来排的,其实我是想把它当做数值来排.
手动转换类型:用下面的方法就可以了,使server_id+0之后再排序,问题解决了,代码如下:
- selectserver_idfromcardserverwheregame_id=1orderbyserver_id+0desclimit10;
- +-----------+
- |server_id|
- +-----------+
- |10|
- |8|
- |7|
- |6|
- |5|
- |4|
- |3|
- |2|
- |1|
- +-----------+
使用MySQL函数CAST/CONVERT:mysql为我们提供了两个类型转换函数:CAST和CONVERT,现成的东西我们怎能放过?
CAST() 和CONVERT() 函数可用来获取一个类型的值,并产生另一个类型的值.
这个类型 可以是以下值其中的一个:
- BINARY[(N)]
- CHAR[(N)]
- DATE
- DATETIME
- DECIMAL
- SIGNED[INTEGER]
- TIME
- UNSIGNED[INTEGER]
所以我们也可以用CAST解决问题,代码如下:
- selectserver_idfromcardserverwheregame_id=1orderbyCAST(server_idasSIGNED)desclimit10;
- +-----------+
- |server_id|
- +-----------+
- |10|
- |8|
- |7|
- |6|
- |5|
- |4|
- |3|
- |2|
- |1|
- +-----------+
也可以使用CONVERT来搞定此问题,代码如下:
- selectserver_idfromcardserverwheregame_id=1orderbyCONVERT(server_id,SIGNED)desclimit10;
- +-----------+
- |server_id|
- +-----------+
- |10|
- |8|
- |7|
- |6|
- |5|
- |4|
- |3|
- |2|
- |1|
- +-----------+
总结:方法有很多要看自己动脑子了,所谓的条条大道通罗马也是这个意思了.