[MySQL场景系列之二] 推荐排序

前言

很多情况下都有有列表页面展示,如购物网站,导航页,甚至搜索引擎都会有列表页。一旦涉及到列表页就会有排序问题,有排序页面,就有人为干预排序,这样才能赚钱嘛

场景描述

现有产品列表,源自表product,字段有product_id,name,现在product_id为2,6,8的产品的店主花了点钱,想把产品推到列表的前面,那么现在该如何处理?

方案1

我在项目中这么干过

select product_id,name from product order by product_id not in (2,6,8) asc limit 10

这样可以满足要求

图1

这里的“not in”也可以换成“<>”。

方案2

通过查找资料发现mysql有这么个函数:field

通俗来说field函数一般这样用

field(id, 'str1', 'str2', 'str3')

在字段id中搜索,如果和str1相同,则返回1,以此类推分别返回1,2,3...没有匹配到的返回0,可以做个小实验

select field(product_id, 2,6,8),product_id,name from product limit 10

图2

这样看起来就明显多了。网上的资料显示我们可以这样来完成这个排序任务
,比如这里stackoverflow

然而我这样写

select product_id,name from product order by field(product_id, 2,6,8) limit 10

得到的结果却是这样的

图3

仔细想想,order by 默认的是asc,所以field返回是0的都排在了前面,而选中的几个返回了1,2,3排在了后面。那么我们把asc改成desc

select product_id,name from product order by field(product_id, 2,6,8) desc limit 10

图4

结果还是和预期不同,仔细看图2,原来无论我们用desc还是asc都无法把排序变成1230000...,所以这个field在这种场景下是无法满足要求的。

顺便提一下,这两种写法

select 1,2,product_id,name from product limit 10

图5

select product_id,name from product order by 2 limit 10

图6

这两种写法都很坑爹,但是还是可以了解下的,第一种写法就是在查询出来的数据的基础上加一列“常数”,比如序号什么的,第二种写法中order by 2 是按第二个字段排序(我也是刚知道,原来字段的顺序还真有用),不信你把order by 2 改成 order by 1和order by 字段数+1试试。

方案3

也是用mysql自带的一个函数,locate
locate(substr, str)返回子串substr在字符串str中第一次出现的位置

同样,先来个测试

select locate(product_id, '2,6,8'),product_id,name from product order by 2 limit 10

图7

这里返回的是1,3,5,因为逗号也算在内了,之所以不用‘268’做为字符串是为了避开26,268,这类id。
看到这个测试之后,我想不用再继续下去了,后续同方案2。

最后总结一句话就是:还是方案1简单粗暴。

推荐阅读更多精彩内容

  • 黎民,泛指普通百姓。 庶民,指一般的民众。 黎庶,指平民大众。 黎氓,亦作“ 黎萌 ”,泛指普通百姓。 黎首,泛指...
    西土瓦大神阅读 3,422评论 0 2
  • 我喜欢回忆一些往事,总是时不时的像个神经病一样,打给曾经的老同学、好朋友,聊起以前各种逗比的、好笑的、遗憾的事情,...
    格心理的格子阅读 182评论 0 0
  • 没有反思的人生不值得过,为什么现在明明是9月10日,我要写成9月11日,因为现在要订做的是明天的计划,唯有早点计...
    易学晓帆阅读 65评论 1 1
  • 1、首先在plist表里边添加Privacy - Location Usage Description和NSLoc...
    绾青丝1219阅读 519评论 0 3