Laravel 按条件特价订购

Laravel order by price with condition special price

我有 table 和下一列(价格,special_price,is_special)。

+-------+------+-----------------+--------------+---------+
| 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' 列为真,则 select '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 并希望在结果中订购并获得查询生成器。

比如我用虚拟属性做的

/**
 * Get current price
 *
 * @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();

我有 2 个过滤器 'Quantity' 和 'Price'。

在这个多重排序中,我想获得按价格排序的产品,然后是按 'qty' 排序的所有产品。 数量 == 0 的产品,需要在所有数量 > 0 的产品之后排在下一个。

请帮帮我。

第一个问题

Query-Builder 没有访问器,您需要select它:

DB::table('products')
   ->select('*')
   ->addSelect(DB::raw('IF(is_special=0, price, special_price ) AS current_price'))
   ->orderBy('current_price')
   ->get();

PS:建议在数据库中排序,想想如果你的产品有paginate,那么它只会在一页的数据上排序它return那个页面。


第二个问题:

  1. qty > 0 AS 1, and qty = 0 AS 0, 然后按 DESC:

  2. 根据 price 的要求订购

  3. 根据 qty 的要求订购

所以产品会把qty > 0放在qty = 0之前,记录qty > 0会按价格排序,然后所有产品按qty排序;以及qty = 0会按价格排序的记录,那么所有按qty排序的产品也是:

$query = Product::query();
$query->orderBy(DB::raw(IF('qty > 0, 1, 0')), 'DESC');
$query->orderBy(DB::raw("IF(is_special=0, price, special_price)"), request('price', 'ASC'));
$query->orderBy('qty', request('qty', 'DESC'));
$query->get();

PS: orderByRaw("if(is_special=0, price, special_price) " . request('price', 'ASC')很容易被SQL-Injection攻击。更改为 orderBy(DB::raw("IF(is_special=0, price, special_price)"), request('price', 'ASC'))