2017-11-08 33 views
0

私はこのクエリを生成し、次のクエリビルダをしている:minとmax価格フィルタリングを使用した場合Laravelの雄弁は

私の問題は、販売およびストックオプションでWHERE条件内にあります。私のURLは次のようになります。

category/men-clothes?sale=no_sale&min_price=10&max_price=10000&per_page=8 

販売= no_saleは、クエリは、したがって、この私のSQLクエリでは、ここで、 'SALE_PRICE' を行い、 '='、0意味:

and `sale_price` = ? order by `id` desc 

しかし、それまだsale_priceが0より大きい製品をフェッチしますが、私がon_saleに切り替えると、sale_priceが0より大きい製品だけがフェッチされます。したがって、問題は、アクティブな販売がない製品を選択する場合のみです。 これは、on_stockとno_stockのところで、適切な製品を取得しないだけです。私は建築業者がかなり大きいことを知っていますが、なぜそれが適切に機能していないのか理解できませんでした。これは、私がmin_priceとmax_priceのフィルタリングを完全に削除した後にのみ正常に動作します。したがって、whereとorWhereのどこかにある必要があります。

select * from `products` where exists (select * from `categories` inner join `product_categories` on `categories`.`id` = `product_categories`.`category_id` where `products`.`id` = `product_categories`.`product_id` and `id` = ?) and (`has_variants` = ? and `price` >= ?) or (`has_variants` = ? and `min_price` != ? and `min_price` >= ?) and (`has_variants` = ? and `price` <= ?) or (`has_variants` = ? and `max_price` != ? and `max_price` <= ?) and `sale_price` = ? order by `id` desc 

$products = Product::whereHas('categories', function ($query) use ($category) { 
      $query->where('id', '=', $category->id); 
     })->when(count($brand_list) > 0, function ($query) use ($brand_list) { 
      $query->whereHas('brand', function ($query) use ($brand_list) { 
       $query->whereIn('slug', $brand_list); 
      }); 
     })->when($minPrice, function ($query) use ($data) { 
      $query->where([ 
        ['has_variants', '=', 0], 
        ['price', '>=', $data['active_filters']['min_price']], 
       ]) 
       ->orWhere([ 
        ['has_variants', '=', 1], 
        ['min_price', '!=', 0], 
        ['min_price', '>=', $data['active_filters']['min_price']], 
       ]); 
     })->when($maxPrice, function ($query) use ($data) { 
      $query->where([ 
       ['has_variants', '=', 0], 
       ['price', '<=', $data['active_filters']['max_price']], 
      ]) 
       ->orWhere([ 
        ['has_variants', '=', 1], 
        ['max_price', '!=', 0], 
        ['max_price', '<=', $data['active_filters']['max_price']], 
       ]); 
     })->when($orderPrice, function ($query) use ($orderPrice) { 
      $query->orderBy('price', $orderPrice); 
     })->when(!$orderPrice, function ($query) { 
      $query->orderBy('id', 'desc'); 
     })->when($stockOrder, function ($query) use ($stockOrder) { 
      if($stockOrder == 'in_stock') { 
       $query->where('quantity', '>', 0); 
      } else if($stockOrder == 'no_stock') { 
       $query->where('quantity', '=', 0); 
      } 
     })->when($saleOrder, function ($query) use ($saleOrder) { 
      if($saleOrder == 'on_sale') { 
       $now = time(); 
       $query->where([ 
        ['sale_price', '>', 0], 
        ['sale_start', '<', $now], 
        ['sale_end', '>', $now], 
       ])->orWhere([ 
        ['sale_price', '>', 0], 
        ['sale_start', '=', 0], 
        ['sale_end', '=', 0], 
       ]); 
      } else if($saleOrder == 'no_sale') { 
       $query->where('sale_price', '=', 0); 
      } 
     })->when($featuredOrder, function ($query) use ($featuredOrder) { 
      if($featuredOrder == 'featured') { 
       $query->where('featured', '=', 1); 
      } else if($featuredOrder == 'not_featured') { 
       $query->where('featured', '=', 0); 
      } 
     })->when(count($activeColors) > 0, function ($query) use ($activeColors) { 
      $query->whereHas('colors', function ($query) use ($activeColors) { 
       $query->whereIn('value', $activeColors); 
      }); 
     })->when(count($activeSizes) > 0, function ($query) use ($activeSizes) { 
      $query->whereHas('sizes', function ($query) use ($activeSizes) { 
       $query->whereIn('value', $activeSizes); 
      }); 
     })->with(['colors', 'sizes', 'reviewsCount'])->get(); 

答えて

1

ここでの問題はorWhereだと思います。あなたが使うときはいつも追加のクロージャーを使って工事をラップするべきです。のは、見てみましょう:

->when($minPrice, function ($query) use ($data) { 
      $query->where([ 
        ['has_variants', '=', 0], 
        ['price', '>=', $data['active_filters']['min_price']], 
       ]) 
       ->orWhere([ 
        ['has_variants', '=', 1], 
        ['min_price', '!=', 0], 
        ['min_price', '>=', $data['active_filters']['min_price']], 
       ]); 
     }) 

この部分はおそらく次のようになります。

->when($minPrice, function ($query) use ($data) { 
     $query->where(function($query) use ($data) { 
      $query->where([ 
        ['has_variants', '=', 0], 
        ['price', '>=', $data['active_filters']['min_price']], 
       ]) 
       ->orWhere([ 
        ['has_variants', '=', 1], 
        ['min_price', '!=', 0], 
        ['min_price', '>=', $data['active_filters']['min_price']], 
       ]); 
      }); 
     }) 

全体where .. orWhereを追加閉鎖に包まれた上でご覧のとおり。

この理由は非常に明白です。あなたはクロージャを使うときに、彼らが作るために照会し、余分な括弧を追加します

WHERE A and (B or C) and (D or E) 

:あなたは追加の閉鎖を持っていない場合は、この

WHERE A and B or C and D or E 

のようなクエリを生成することができ、通常は、このようにする必要がありますそれは働く。

あなたは明らかにあなたが

+0

うん、おかげで期待通りに動作させるために他のすべてwhere ... orWhereの構造をラップする必要があると同じように。私はちょうどどこにそれらを囲む余分ですべての私のwhere句をラップする必要がありました。どうもありがとうございます!それは今の魅力のように機能します。 –