Laravel Красноречивый запрос с условием ИЛИ ГДЕ - PullRequest
0 голосов
/ 01 мая 2020

Я использую 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

Теперь идентификатор 112 удален, но все еще отображается в результате, хотя у меня есть условие where ('Удалено_,', 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);

1 Ответ

2 голосов
/ 01 мая 2020

Это потому, что оператор 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) ) 

Я не уверен, что вы действительно хотите ИЛИ что-нибудь. Если вы действительно хотите применить все условия, вам просто нужно изменить orWhereIn на whereIn.


Если вы хотите, чтобы все не удаленные задачи принадлежали ЛИБО компании и АУСЕР ИЛИ, чей идентификатор находится в списке, вам необходимо обновить ваш запрос следующим образом:

$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.

...