Как сделать два предложения ГДЕ внутри вложенного СО - PullRequest
0 голосов
/ 19 сентября 2018

У меня есть следующий код:

$sectors = Sector::where('company_id', $id)
                 ->where('status', '0')
                 ->with('charges.levels')
                 ->get();

и мне нужно 3 условия

  • Статус сектора будет 0
  • Статус сборов будет 0
  • Статус уровней будет 0

Итак, я хочу знать:

  • Как использовать WHERE для поиска статуса зарядов 0 и статуса уровней 0когда они вложены в: -> with ('charge.levels')

Код имеет следующие отношения:

  • Сектор имеет много зарядов иЗаряд относится к сектору
  • Заряд имеет много уровней, и уровень принадлежит заряду

Итак, я хочу привести все уровни, где статус уровня равен 0, статус заряда равен0 и статус сектора 0

Ответы [ 2 ]

0 голосов
/ 19 сентября 2018
$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.

0 голосов
/ 19 сентября 2018

Вы можете запрашивать отношения, подобные этому, когда вы стремитесь к загрузке:

$sectors = Sector::where('company_id', $id)
    ->with([
        'charges' => function ($query) {
            $query->where('status', 0);
        },
        'charges.levels' => function ($query) {
            $query->where('status', 0);
        }
    ])
    ->get();

Для получения дополнительной информации об ограничении нетерпеливой загрузки: https://laravel.com/docs/5.7/eloquent-relationships#constraining-eager-loads

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...