如何在嵌套WITH中执行两个子句

时间:2018-09-19 17:11:12

标签: php laravel eloquent

我有以下代码:

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

我需要3个条件

  • 扇区状态为0
  • 收费状态为0
  • 状态为0

所以我想知道:

  • 如何使用WHERE搜索收费状态0和状态 当它们嵌套在以下级别中时为0:-> with('charges.levels')

代码具有以下关系:

  • 一个部门有很多收费,而收费属于一个部门
  • 收费有多个级别,一个级别属于收费

所以,我想带所有级别为0的级别,充电状态为0且扇区的状态为0

2 个答案:

答案 0 :(得分:1)

当您渴望加载时,可以查询如下关系:

$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

答案 1 :(得分:0)

$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

但是请小心。口才不执行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限制,如果该表很大和/或{ {1}}未建立索引。这与说sector.status查询相反,该查询可以充分利用合并搜索条件的优势。使用JOIN时,附加条件通常可以提高性能,但使用JOIN时则相反。因此,使用以下命令可能会更好:https://laravel.com/docs/5.7/queries#joins