Laravel sort by price with special price conditions
P粉030479054
P粉030479054 2023-09-22 13:06:46
0
1
1163

I have a table with the following columns (price, special offer, whether on sale).

+-------+------+-----------------+--------------+---------+
| 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       |
+-------+-------+-----------------+--------------+---------+

I want to get the products sorted by 'price', and if the 'is_special' column is true, select the 'special_price' column.

I want the following results.

+-------+-----------+-----------------+--------------+--------------+
| 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          |
+-------+-----------+-----------------+--------------+--------------+

In raw SQL it looks like

SELECT *
FROM products
ORDER BY IF(is_special=0, price, special_price ) ASC;

I'm using Laravel and want to sort the query builder and get the results.

For example, I did this using virtual properties

/**
 * 获取当前价格
 *
 * @return mixed
 */
 public function getCurrentPriceAttribute()
 {
     return $this->is_special ? $this->special_price : $this->price;
 }

Then sort the collection$products->sortBy('current_price'), but this time I want to get the query builder in the results. Query Builder cannot use virtual properties.

I tried multiple sorting by two columns 'price' and 'qty'

$query = Product::query();

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

$query->get();

I have two filters 'quantity' and 'price'.

In this multiple sort, I want to sort the products by price and then sort all the products by 'qty'. Products with qty == 0 need to follow all products with qty > 0.

please help me.

P粉030479054
P粉030479054

reply all(1)
P粉207969787

first question

The query builder has no accessor, you need to select it out:

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

PS: It is recommended to sort in the database, consider that if you have paginate on the product, it will only sort the returned page data.


second question:

  1. qty > 0 AS 1, qty = 0 AS 0, then sort in descending order:

  2. Sort by requested price

  3. Sort by requested qty

So the product will put qty > 0 before qty = 0, and then sort the records of qty > 0 by price, and then all Products are sorted by qty; records with qty = 0 will be sorted by price, and then all products are also sorted by 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')Vulnerable toSQL injection attack. Change to orderBy(DB::raw("IF(is_special=0, price, special_price)"), request('price', 'ASC'))

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template