我有一个带有以下列(价格,特价,是否特价)的表。
+-------+------+-----------------+--------------+---------+ | id | price | special_price | is_special | qty | +-------+-------------------------+--------------+----------+ | 1 | 100 | null | 0 | 5 | | 2 | 120 | 99 | 1 | 0 | | 3 | 300 | null | 0 | 1 | | 4 | 400 | 350 | 1 | 10 | | 5 | 75 | 69 | 1 | 0 | | 6 | 145 | 135 | 0 | 1 | +-------+-------+-----------------+--------------+---------+
我想按照'price'排序获取产品,如果'is_special'列为true,则选择'special_price'列。
我想要以下结果。
+-------+-----------+-----------------+--------------+--------------+ | id | price | special_price | is_special | qty | +-------+-----------------------------+--------------+--------------+ | 5 | 75 | 69 | 1 | 0 | | 2 | 120 | 99 | 1 | 0 | | 1 | 100 | null | 0 | 5 | | 6 | 145 | 135 | 0 | 1 | | 3 | 300 | null | 0 | 1 | | 4 | 400 | 350 | 1 | 10 | +-------+-----------+-----------------+--------------+--------------+
在原始SQL中,它看起来像
SELECT * FROM products ORDER BY IF(is_special=0, price, special_price ) ASC;
我正在使用Laravel,并希望对查询生成器进行排序并获取结果。
例如,我使用虚拟属性完成了这个操作
/** * 获取当前价格 * * @return mixed */ public function getCurrentPriceAttribute() { return $this->is_special ? $this->special_price : $this->price; }
然后对集合进行排序$products->sortBy('current_price')
,但这次我想在结果中获取查询生成器。 查询生成器无法使用虚拟属性。
我尝试通过两个列'price'和'qty'进行多重排序
$query = Product::query(); $query->orderByRaw("if(is_special=0, price, special_price) " . request('price', 'ASC')); $query->orderBy('qty', request('qty', 'DESC')); $query->get();
我有两个过滤器'数量'和'价格'。
在这个多重排序中,我想按照价格排序产品,然后按照'qty'排序所有产品。 qty == 0的产品需要在qty > 0的所有产品之后。
请帮助我。
第一个问题
查询构建器没有访问器,你需要将其选择出来:
PS:建议在数据库中进行排序,考虑一下如果在产品上有
paginate
,它将只对返回的页面数据进行排序。第二个问题:
qty > 0
AS 1,qty = 0
AS 0,然后按降序排序:按请求的
price
排序按请求的
qty
排序所以产品将把
qty > 0
放在qty = 0
之前,然后将qty > 0
的记录按照价格排序,然后所有产品按照qty
排序;qty = 0
的记录将按照价格排序,然后所有产品也按照qty
排序:PS:
orderByRaw("if(is_special=0, price, special_price) " . request('price', 'ASC')
容易受到SQL注入的攻击。改为orderBy(DB::raw("IF(is_special=0, price, special_price)"), request('price', 'ASC'))