如何在 laravel 中使用分组 OR 表达式复制 SQL

问题描述 投票:0回答:1

我希望实现一个搜索功能,其中可以选择包含供用户搜索的各个字段。

到目前为止我的代码:

        $categories = $request->input('category'); // array(int)
        $textSearch = $request->input('text'); // string

        $query = Product::query();

        if(!is_null($categories)){
            //$query->selectSub();
            foreach($categories as $catId){
                $category = ShopCategory::find($catId);

                $query = $query->whereBelongsTo($category);//TODO
            }
        }
        if(!is_null($textSearch)){
            $query = $query->whereAny([
                'name',
                'description',
                'shortDescription',
            ],
                'like', '%'.$textSearch.'%');
        }

        $searchResults = $query->paginate(36);

我的目标是达到相当于以下内容的 SQL 语句:

SELECT * FROM products WHERE (shop_category_id = ? OR shop_category_id = ?) AND (/* text search LIKE */)

但到目前为止,我最终得到的更多的是:

SELECT * FROM products WHERE shop_category_id = ? AND shop_category_id = ? AND (/* text search LIKE */)

每个类别 ID 都作为整体查询的一部分进行

AND
编辑,而不是在组中进行
OR
编辑。

我知道

or*()
查询方法,但不清楚如何正确地将它们分组以获得所需的效果,而不是仅仅将它们与文本搜索一起
OR

laravel eloquent laravel-11
1个回答
0
投票

您可以使用带有回调的

where
函数将一些 where 条件包装到一个组中。回调内应用于构建器的任何条件都将被包裹在括号中。例如:

Model::query()->where('condition1', 'value')->where(function($query) {
  // those where will be wrapped into ()
  $query->where('condition2', 'value')->orWhere('condition3', 'value');
})

将给出以下查询:

SELECT *
FROM models
WHERE conditon1 = 'value'
  AND (condition2 = 'value'
       OR condition3 = 'value')

并且由于第一个位置是

OR
AND
并不重要,因此您可以将其放入循环中,而不必担心第一个
OR
:

$columns = [
 'column1', 
 'column2',
 'column3'
]

Model::query()->where('condition1', 'value')->query(function($query) use ($columns) {
  foreach($columns as $column) {
    $query->orWhere($column, 'value');
  } 
});

此查询是动态生成的,将返回以下 SQL:

SELECT *
FROM models
WHERE condition1 = 'value'
  AND (column1 = 'value'
       OR column2 = 'value'
       OR column3 = 'value')

并且由于“列条件”被包装到一个组中,因此它们不会干扰第一个条件。

© www.soinside.com 2019 - 2024. All rights reserved.