首页 > 解决方案 > 带有 OR WHERE 条件的 Laravel Eloquent 查询

问题描述

我正在使用 Laravel 6 和 mysql 7

我有以下查询

$tasks = Task::where('deleted_at', null)->where('company_id',$company_id);
$tasks = $tasks->where('created_by',$user_id);
$tasks = $tasks->orWhereIn('id',$task_ids);

当我打印它时它会生成下面的原始查询

SELECT * FROM `tasks` WHERE `deleted_at` IS NULL AND  `company_id` = 25 AND `created_by` = 20 OR 
`id` IN(112,...215) ORDER BY `id` DESC

现在 ID 112 已被删除但仍显示在结果中,虽然我有 where('deleted_at', null) 条件但它不起作用

$task_ids我也想应用所有其他条件

如何通过优化查询来实现这一点?

更新:这是完整的场景

我想选择由我创建或分配给我的所有记录。这是我的完整代码。

 $tasks = Task::where('deleted_at', null)->where('company_id',$company_id);
 $tasks = $tasks->where('created_by',$user_id);
 $task_ids = TaskUser::where('user_id',$user_id)->pluck('task_id')->all();
 $tasks = $tasks->orWhereIn('id',$task_ids);

标签: laraveleloquentwhere-clause

解决方案


这是因为 AND 运算符的优先级高于 OR,这基本上意味着 AND 比 OR 更能“粘”在一起。您的查询基本上是这样解释的:

SELECT * FROM `tasks` 
WHERE 
    (`deleted_at` IS NULL AND  `company_id` = 25 AND `created_by` = 20) 
  OR 
    ( `id` IN(112,...215) ) 

我不确定您是否真的想要或任何东西。如果您真的想应用所有条件,只需将 更改orWhereInwhereIn.


如果您想要所有未删除的任务,即属于公司和用户或者其 id 在列表中,您需要像这样更新您的查询:

$tasks = Task::where('deleted_at', null);

$tasks = $tasks->where(function($q) use ($user_id, $task_ids){

    $q->where(function($q2) use ($user_id, $task_ids) {
        $q2->where('created_by',$user_id)
           ->where('company_id',$company_id);
    })
      ->orWhereIn('id',$task_ids);
});

这应该导致这个查询:

SELECT * FROM `tasks` 
WHERE `deleted_at` IS NULL AND ( 
  ( `company_id` = 25 AND `created_by` = 20 )
  OR
  `id` IN(112,...215) 
) 

在优秀的 laravel 文档中实际上也有一章关于参数分组。


推荐阅读