前言
很多情况下都有有列表页面展示,如购物网站,导航页,甚至搜索引擎都会有列表页。一旦涉及到列表页就会有排序问题,有排序页面,就有人为干预排序,这样才能赚钱嘛
场景描述
现有产品列表,源自表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,可以做个小实验
图2select field(product_id, 2,6,8),product_id,name from product limit 10
这样看起来就明显多了。网上的资料显示我们可以这样来完成这个排序任务
,比如这里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
图4select product_id,name from product order by field(product_id, 2,6,8) desc limit 10
结果还是和预期不同,仔细看图2,原来无论我们用desc还是asc都无法把排序变成1230000...,所以这个field在这种场景下是无法满足要求的。
顺便提一下,这两种写法
图5select 1,2,product_id,name from product limit 10
图6select product_id,name from product order by 2 limit 10
这两种写法都很坑爹,但是还是可以了解下的,第一种写法就是在查询出来的数据的基础上加一列“常数”,比如序号什么的,第二种写法中order by 2 是按第二个字段排序(我也是刚知道,原来字段的顺序还真有用),不信你把order by 2 改成 order by 1和order by 字段数+1试试。
方案3
也是用mysql自带的一个函数,locate
locate(substr, str)返回子串substr在字符串str中第一次出现的位置
同样,先来个测试
图7select locate(product_id, '2,6,8'),product_id,name from product order by 2 limit 10
这里返回的是1,3,5,因为逗号也算在内了,之所以不用‘268’做为字符串是为了避开26,268,这类id。
看到这个测试之后,我想不用再继续下去了,后续同方案2。
最后总结一句话就是:还是方案1简单粗暴。
网友评论