Laravel заказ по цене с условием специальной цены - PullRequest
1 голос
/ 24 марта 2020

У меня есть таблица со следующими столбцами (цена, 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' имеет значение true, тогда выберите 'special_price 'column.

Я хочу получить следующий результат.

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

Помогите, пожалуйста.

1 Ответ

2 голосов
/ 24 марта 2020

Первая проблема

У 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, затем заказывайте их DES C:

  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'))

...