【问题标题】:How to add brackets around WHERE conditions with Laravel query builder如何使用 Laravel 查询生成器在 WHERE 条件周围添加括号
【发布时间】:2014-05-06 20:30:24
【问题描述】:

我正在使用 Laravel 查询构建器根据用户的过滤器选择动态过滤数据:

 $query = DB::table('readings');
 foreach ($selections as $selection) {
   $query->orWhere('id', $selection);
 }
 $query->whereBetween('date', array($from, $to));
 $query->groupBy('id');

当我检查 SQL 时,我得到如下信息:

select count(*) as `count` from `readings` where `id` = 1 or id` = 2 and `date` between "2013-09-01" and "2013-09-31" group by `id`;

但我需要的是这样的(在 or 语句周围有括号):

select count(*) as `count` from `readings` where (`id` = 1 or id` = 2) and `date` between "2013-09-01" and "2013-09-31" group by `id`;

如何使用 Laravel 查询构建器在 WHERE 条件周围添加括号?

【问题讨论】:

    标签: mysql laravel


    【解决方案1】:

    有时您可能需要在括号内对多个“where”子句进行分组,以实现查询所需的逻辑分组。事实上,您通常应该始终将 orWhere 方法的调用组合在括号中,以避免意外的查询行为。为此,您可以将闭包传递给 where 方法:

    $users = DB::table('users')
               ->where('name', '=', 'John')
               ->where(function ($query) {
                   $query->where('votes', '>', 100)
                         ->orWhere('title', '=', 'Admin');
               })
               ->get();
    

    如您所见,将闭包传递给 where 方法会指示查询构建器开始一个约束组。闭包将收到一个查询构建器实例,您可以使用它来设置应包含在括号组中的约束。上面的示例将产生以下 SQL:

    select * from users where name = 'John' and (votes > 100 or title = 'Admin')
    

    【讨论】:

      【解决方案2】:

      很有用,我用这个:

      ->where(function ($query) use ($texto){
          $query->where('UPPER(V_CODIGO)', 'LIKE', '%'.Str::upper($texto).'%')
                ->orWhere('UPPER(V_NOMBRE)', 'LIKE', '%'.Str::upper($texto).'%');
      });
      

      【讨论】:

      • 即使您的答案中的代码可能提供有用的解决方案,请使用英文进行解释:)
      【解决方案3】:

      我在文档中找不到这个,whereNested 正是我要找的。希望它可以帮助任何人。

      $q->whereNested(function($q) use ($nameSearch) {
          $q->where('name', 'LIKE', "%{$nameSearch}%");
          $q->orWhere('surname', 'LIKE', "%{$nameSearch}%");
      });
      

      注意:这是在 Laravel 4.2 上

      【讨论】:

      • 对于 laravel 5.1 查看“Gonzalo Tito”的答案,它看起来很相似,也没有记录,但它有效且直观。
      【解决方案4】:

      通过使用闭包自己解决了这个问题,如查询生成器文档中的 Parameter Grouping 所述。

       $query = DB::table('readings');
       $this->builder->orWhere(function($query) use ($selections)
       {
          foreach ($selections as $selection) {
             $query->orWhere('id', $selection);
          }
       });
       $query->whereBetween('date', array($from, $to));
       $query->groupBy('id');
      

      【讨论】:

      • 添加了替代方案,但我认为您的版本更擅长处理来自$selection 的空结果。如果 id 为空,也许它们都失败了,我不确定。我想这取决于如果没有可供选择的 ID,您想要发生什么。无论如何,你的答案是对标题中问题的更一般的回答。
      【解决方案5】:

      你可以在这里使用WHERE IN 来达到同样的效果:

      $query = DB::table('readings');
      $query->whereIn('id', $selection)
      $query->whereBetween('date', array($from, $to));
      $query->groupBy('id');
      

      【讨论】:

        猜你喜欢
        • 2013-12-09
        • 2021-01-29
        • 2014-02-21
        • 2020-01-22
        • 2014-08-20
        • 1970-01-01
        • 1970-01-01
        • 2016-08-16
        • 2019-05-06
        相关资源
        最近更新 更多