Не удается управлять построителем запросов Laravel

$a = 0;
$searchqueryMake = 'whereHas';
foreach ($options as $param)
{
if($a>0 && $searchCriteria == 2)
{
$searchqueryMake = 'orWhereHas';
$u = ($u->$searchqueryMake('option', function($q) use($param){
$q->where('option_id', '=', $param );
}));
}
else
{
$u = ($u->$searchqueryMake('option', function($q) use($param){
$q->where('option_id', '=', $param );
}));
}
$a++;
}

$a = 0;
$searchqueryMake = 'whereHas';
foreach ($specific_University as $param)
{
if($a>0 && $searchCriteria == 2)
{
$searchqueryMake = 'orWhereHas';
$u = $u->$searchqueryMake('degree', function($q) use($param){
$q->whereHas('university', function($q) use($param){
$q->where('id', '=', $param);
});
});
}
else
{
$u = $u->$searchqueryMake('degree', function($q) use($param){
$q->whereHas('university', function($q) use($param){
$q->where('id', '=', $param);
});
});
}
$a++;
}

Я написал этот код для получения ниже результата SQL
Для И условия SQL результат будет следующим:

    select * from `users` where `group_id` = ? and
(select count(*) from `options` inner join `user_option` on `options`.`id` = `user_option`.`option_id` where
`user_option`.`user_id` = `users`.`id` and
`option_id` = ?) >= 1 and
(select count(*) from `options` inner join `user_option` on `options`.`id` = `user_option`.`option_id` where
`user_option`.`user_id` = `users`.`id` and `option_id` = ?) >= 1 and
(select count(*) from `degrees` inner join `user_degree` on `degrees`.`id` = `user_degree`.`degree_id` where
`user_degree`.`user_id` = `users`.`id` and
(select count(*) from `universities` where
`degrees`.`university_id` = `universities`.`id` and
`id` = ?) >= 1) >= 1 and
(select count(*) from `degrees` inner join `user_degree` on `degrees`.`id` = `user_degree`.`degree_id` where
`user_degree`.`user_id` = `users`.`id` and
(select count(*) from `universities` where
`degrees`.`university_id` = `universities`.`id` and
`id` = ?) >= 1) >= 1 and
(select count(*) from `degrees` inner join `user_degree` on `degrees`.`id` = `user_degree`.`degree_id` where
`user_degree`.`user_id` = `users`.`id` and
(select count(*) from `universities` where
`degrees`.`university_id` = `universities`.`id` and
`id` = ?) >= 1) >= 1

и еще раз, когда пользователь выбирает или обусловливает результат sql —

    select * from `users` where `group_id` = ? and
(select count(*) from `options` inner join `user_option` on `options`.`id` = `user_option`.`option_id` where
`user_option`.`user_id` = `users`.`id` and
`option_id` = ?) >= 1 or
(select count(*) from `options` inner join `user_option` on `options`.`id` = `user_option`.`option_id` where
`user_option`.`user_id` = `users`.`id` and `option_id` = ?) >= 1 and
(select count(*) from `degrees` inner join `user_degree` on `degrees`.`id` = `user_degree`.`degree_id` where
`user_degree`.`user_id` = `users`.`id` and
(select count(*) from `universities` where
`degrees`.`university_id` = `universities`.`id` and `id` = ?) >= 1) >= 1 or
(select count(*) from `degrees` inner join `user_degree` on `degrees`.`id` = `user_degree`.`degree_id` where
`user_degree`.`user_id` = `users`.`id` and
(select count(*) from `universities` where
`degrees`.`university_id` = `universities`.`id` and
`id` = ?) >= 1) >= 1 or
(select count(*) from `degrees` inner join `user_degree` on `degrees`.`id` = `user_degree`.`degree_id` where
`user_degree`.`user_id` = `users`.`id` and
(select count(*) from `universities` where
`degrees`.`university_id` = `universities`.`id` and
`id` = ?) >= 1) >= 1

Самый верхний запрос хорош, потому что все условия в AND. Но нижняя часть не получает правильное значение, потому что там нам нужны все условия И и ИЛИ, а также необходимо разделить их скобками, чтобы получить правильный результат, который я не могу сделать с помощью этого красноречивого метода. Может ли кто-нибудь помочь мне выяснить эту проблему …

Точный запрос это то, что мне нужно —

select * from `users` where `group_id` = ? and
((select count(*) from `options` inner join `user_option` on `options`.`id` = `user_option`.`option_id` where
`user_option`.`user_id` = `users`.`id` and
`option_id` = ?) >= 1 or
(select count(*) from `options` inner join `user_option` on `options`.`id` = `user_option`.`option_id` where
`user_option`.`user_id` = `users`.`id` and `option_id` = ?) >= 1) and
((select count(*) from `degrees` inner join `user_degree` on `degrees`.`id` = `user_degree`.`degree_id` where
`user_degree`.`user_id` = `users`.`id` and
(select count(*) from `universities` where
`degrees`.`university_id` = `universities`.`id` and `id` = ?) >= 1) >= 1 or
(select count(*) from `degrees` inner join `user_degree` on `degrees`.`id` = `user_degree`.`degree_id` where
`user_degree`.`user_id` = `users`.`id` and
(select count(*) from `universities` where
`degrees`.`university_id` = `universities`.`id` and
`id` = ?) >= 1) >= 1 or
(select count(*) from `degrees` inner join `user_degree` on `degrees`.`id` = `user_degree`.`degree_id` where
`user_degree`.`user_id` = `users`.`id` and
(select count(*) from `universities` where
`degrees`.`university_id` = `universities`.`id` and
`id` = ?) >= 1) >= 1))

0

Решение

Хорошо, это довольно большой запрос, и, честно говоря, у меня нет времени, чтобы подробно его рассмотреть. Но вот как вы можете заключить в скобки практически все условия. Это называется вложенный где

Во-первых, вот несколько нормальных типов:

where('foo', 'foo')->orWhere('foo', 'bar')->where('bar', 'bar')

Это приводит к:

WHERE foo = 'foo' OR foo = 'bar' AND bar = 'bar'

Который будет выполнен как:

WHERE foo = 'foo' OR ( foo = 'bar' AND bar = 'bar' )

Чтобы изменить это, мы можем добавить где с закрытием:

where(function($query){
$query->where('foo', 'foo');
$query->orWhere('foo', 'bar');
})->where('bar', 'bar');

Теперь SQL выглядит так:

WHERE ( foo = 'foo' OR foo = 'bar' ) AND bar = 'bar'

Я надеюсь, что вы можете работать с этим и соответствующим образом изменить свой код.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]