Sequelize 排序问题:将字符串类型字段转数字类型后进行排序

问题出现场景:

目前使用egg框架进行后端业务开发,使用sequlize这个ORM进行数据库的操作;今天,遇到一个需求,要按照一个被数据库定义为VARCHAR的字段code,按照降序进行排列。

// 原始数据 仅展示 code 字段

['999', '2', '11', '23', '300', '856',  '7869', '66', '88', '1234444', '3333']

// 理想结果

res ->  ['1234444', '7869', '3333', '999', '856', '300', '88', '66', '23', '11', '2']

  我按照常规的处理方法,进行操作,输出的结果,大概是这样的。如下: 

this.ctx.model.xxx.findAndCountAll({
   offset,
   limit,
   order: [['code', 'DESC']],
});

// 结果

res -> ['999', '88', '856', '7869', '66', '3333', '300', '23', '2', '1234444', '11']

显然,这样的结果不是我们想要的。这样的排序输出,与前端开发中,字符串数组按照ASCII码排序的结果一致。例如:

// 沿用原始数据
const a = ['999', '2', '11', '23', '300', '856',  '7869', '66', '88', '1234444', '3333'];

a.reverse(); 
// 执行结果 -> ['999', '88', '856', '7869', '66', '3333', '300', '23', '2', '1234444', '11']

至于mysql中的排序规则,没有去查,原理应该是类似的。到此,其实也找到了问题的所在,就是数字字符串,并没有按照纯数字的规则进行排序,而是按照字符串的规则进行排序,而字符串的排序规则,又是按照ASCII码进行的;

解决方案:

由于不是后端开发,所以遇到这个问题,有点方,也是各种搜百度;

最后确认了三种处理方法:

1、纯sql语句,简单地在要排序的字段后 *1或者 +1即可;

2、纯sql语句,使用MySQL绝对值函数ABS(字段名);

3、纯sql语句,使用ORDER BY CAST(字段名 AS SIGNED);

// 实现 1

SELECT * FROM table1 ORDER BY code + 1 DESC;

// 实现 2

SELECT * FROM table1 ORDER BY code * 1 DESC;

// 实现 3

SELECT * FROM table1 ORDER BY ABS(code) DESC;

// 实现 4

SELECT * FROM table1 ORDER BY CAST(code as SIGNED) DESC;

对比以上纯sql的实现,要通过sequelize进行实现的话,好像只有第3种方法可以进行修改;

接下来就是找sequelize中对应的CAST( * as SIGNED) 的方法了;

在sequelize官方文档中,看到的cast()方法,但是type参数并没有罗列对应的枚举值;参考:http://sequelize.org/master/class/lib/sequelize.js~Sequelize.html

然后查mysql对应的方法入参,发现 SIGNED  对应了int类型。所以最终的的sequelize写法如下:

this.ctx.model.table.findAndCountAll({
  order: [[sequelize.cast(sequelize.col('code'), 'SIGNED'), 'DESC']],
});

这里还有一个坑,如果只是sequelize.cast('code', 'SIGNED')的话,排序是不生效的;只有写成代码块中的写法,才能正常执行;

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值