【问题标题】:Laravel order by price with condition special priceLaravel 按价格订购,有条件特价
【发布时间】:2020-07-04 11:47:13
【问题描述】:

我的表格包含下一列(price、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       |
+-------+-------+-----------------+--------------+---------+

我想获取带有条件的“价格”订购的产品,如果“is_special”列为真,则选择“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'),但此时我想获得查询生成器的结果。 查询生成器不适用于虚拟属性。

我正在尝试按“价格”和“数量”两列进行多重排序

$query = Product::query();

$query->orderByRaw("if(is_special=0, price, special_price) " . request('price', 'ASC'));
$query->orderBy('qty', request('qty', 'DESC'));

$query->get();

我有 2 个过滤器“数量”和“价格”。

在这个多重订购中,我想按价格订购产品,然后按“数量”订购所有产品。 qty == 0 的产品,需要排在所有 qty > 0 的产品之后。

请帮帮我。

【问题讨论】:

  • 也发布您的查询...

标签: php mysql laravel eloquent laravel-query-builder


【解决方案1】:

第一个问题

Query-Builder 没有访问器,你需要选择它:

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

PS:建议在数据库中排序,考虑一下如果你的产品上有paginate,返回该页面时只会对该页面的数据进行排序。


第二个问题:

  1. qty > 0 AS 1 和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();

PSorderByRaw("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'))

【讨论】:

  • 非常感谢您的帮助。我尝试使用您的代码,但订购 $query->orderBy('qty', request('qty', 'DESC')); 的数量无法满足请求。我向数量订购添加了请求,它工作正常。 $query->orderBy(DB::raw("IF(qty > 0, 1, 0)"), request('qty', 'DESC')); $query->orderBy(DB::raw("IF(is_special = 0, price, special_price)"), request('price', 'ASC')); 这个工作正常,但我不能拆分这 2 个过滤器。我想创建 2 个独立的方法。
  • @tosky 我试了一下,效果很好。如果qty > 0的记录与价格相同,则按数量排序。你能告诉我结果有什么问题吗?
  • 一切正常。你真的帮助了我,非常感谢!
猜你喜欢
  • 2015-09-07
  • 1970-01-01
  • 2019-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多