Laravel实现优先取高优先级商品再随机取商品的单查询方案
单查询实现优先取高优先级商品,无则随机返回的需求
数据表结构
products表简化结构如下:
+--------+-----------+----------+ | id | name | priority | +--------+-----------+----------+ | 1 | Product 1 | null | | 2 | Product 2 | 1 | | 3 | Product 3 | null | | 4 | Product 4 | null | | 5 | Product 5 | null |
需求
用户每次点按钮返回一个商品:
- 优先拿
priority > 0的商品,按priority从小到大排序返回 - 要是没有这类商品,就随机返回一个(另有逻辑避免重复返回)
现有实现(两次查询)
$product = Product::where('priority', '>', 0)->sortBy('priority')->first(); if(!$product) { $product = Product::orderByRaw('Rand()')->first(); }
单查询解决方案
用条件排序就能把两次查询合并成一次,不用大改现有代码,直接替换原查询逻辑即可:
$product = Product::orderByRaw('CASE WHEN priority > 0 THEN 0 ELSE 1 END') ->orderByRaw('CASE WHEN priority > 0 THEN priority ELSE RAND() END') ->first();
逻辑拆解
- 第一个
orderByRaw:先把priority > 0的商品排在最前面,其余商品往后排,确保高优先级商品被优先检索 - 第二个
orderByRaw:- 对高优先级商品,按
priority升序排序,取第一个符合原逻辑 - 对无优先级商品,用
RAND()随机排序后取第一个,实现随机返回的效果
- 对高优先级商品,按
如果项目使用PostgreSQL数据库,只需把RAND()替换为RANDOM()即可,其余逻辑保持不变。
内容的提问来源于stack exchange,提问作者BobbyP
相关产品推荐
相关产品推荐

