You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Yii Query Builder编写符合预期的SQL关联查询

问题根因

Yii Query Builder的条件拼接遵循SQL逻辑运算符优先级,链式调用andWhere()、orWhere()时不会自动为独立条件块添加分组括号:你在orWhere()之后调用的所有andWhere(),默认会作用于整个WHERE层级的条件,而非仅绑定到OR后面的条件组,最终就会出现条件嵌套混乱、逻辑和预期不符的问题。

正确实现代码

要完全匹配你给出的原生SQL逻辑,需要将OR两侧的条件分别封装为独立的逻辑分组,再统一拼接,避免优先级错乱:

Table1::find()
    ->joinWith(['table2'])
    ->where([
        'or',
        // OR 左侧的条件组
        [
            'and',
            ['Table1.idOwner' => $idOwner, 'Table2.enabled' => 1],
            ['<=', 'day(Table2.creationDate)', $expirationDay],
            ['=', "date_format(Table2.creationDate, '%Y-%m')", $previousExpirationMonthYear]
        ],
        // OR 右侧的条件组
        [
            'and',
            ['Table1.idOwner' => $idOwner, 'Table2.enabled' => 1],
            ['!=', "date_format(Table2.creationDate, '%Y-%m')", $currentExpirationMonthYear],
            ['!=', "date_format(Table2.creationDate, '%Y-%m')", $previousExpirationMonthYear]
        ]
    ])
    ->all();
优化写法

观察原SQL逻辑可以发现,两个OR条件组都包含公共条件Table1.idOwner = 156 AND Table2.enabled = 1,可以把公共条件提取出来简化代码,生成的SQL执行逻辑完全一致:

Table1::find()
    ->joinWith(['table2'])
    ->where([
        'and',
        // 公共前置条件
        ['Table1.idOwner' => $idOwner, 'Table2.enabled' => 1],
        [
            'or',
            // 第一组分支条件
            [
                'and',
                ['<=', 'day(Table2.creationDate)', $expirationDay],
                ['=', "date_format(Table2.creationDate, '%Y-%m')", $previousExpirationMonthYear]
            ],
            // 第二组分支条件
            [
                'and',
                ['!=', "date_format(Table2.creationDate, '%Y-%m')", $currentExpirationMonthYear],
                ['!=', "date_format(Table2.creationDate, '%Y-%m')", $previousExpirationMonthYear]
            ]
        ]
    ])
    ->all();

调用getRawSql()即可验证生成的语句和预期原生SQL逻辑完全匹配,不会出现多余的错误嵌套条件。


内容的提问来源于stack exchange,提问作者Carlos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 20:24:29