$sectors = Sector::where('company_id', $id)->where('status', 0)
->whereHas('charges', function (\Illuminate\Database\Eloquent\Builder $query) {
$query->where('status', 0)
->whereHas('levels', function (\Illuminate\Database\Eloquent\Builder $query) {
$query->where('status', 0);
});
})->get();
https://laravel.com/docs/5.7/eloquent-relationships#querying-relationship-existence
Будьте осторожны с этим, хотя.Eloquent не выполняет операторы JOIN (за исключением случаев belongsToMany
отношений).with()
просто выполняет отдельные запросы, использующие операторы IN()
, заполненные предыдущими, а whereHas()
создаст подзапрос.Таким образом, вышеприведенный запрос создаст запрос, который будет выглядеть примерно так:
SELECT *
FROM sector
WHERE
status = 0
AND EXISTS (
SELECT *
FROM charge
WHERE
charge.sector_id = sector.id
AND status = 0
AND EXISTS (
SELECT *
FROM levels
WHERE
levels.charge_id = charge.id
AND status = 0
)
);
Я не знаю о других механизмах БД, но MySQL не очень хорош в обработке подзапросов.Если вы сделаете EXPLAIN
для этого, количество начальных записей, которые будут извлечены для запроса, будет ограничено только sector.status
, что может быть проблемой, если эта таблица большая и / или sector.status
нетиндексируются.Это, в отличие от этого, запрос JOIN
, который может в полной мере использовать объединение критериев поиска.При JOIN
s дополнительные критерии обычно улучшают производительность, но с EXITS
s все наоборот.Так что, возможно, вам повезет больше, если использовать это: https://laravel.com/docs/5.7/queries#joins.