首頁  >  問答  >  主體

Laravel按價格排序,帶有特殊價格條件

我有一個以下列(價格,特價,是否特價)的表。

+-------+------+-----------------+--------------+---------+
| 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的產品之後。

請幫我。

P粉030479054P粉030479054414 天前1125

全部回覆(1)我來回復

  • P粉207969787

    P粉2079697872023-09-23 10:17:23

    第一個問題

    查詢建構器沒有存取器,你需要將其選擇出來:

    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,然後依降序排序:

    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注入的攻擊。改為orderBy(DB::raw("IF(is_special=0, price, special_price)"), request('price', 'ASC'))

    回覆
    0
  • 取消回覆