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

Yii框架2 ActiveRecord中如何使用带比较条件的关联预加载

问题根因

Yii框架的预加载(Eager Loading)逻辑中,关联定义里直接使用$this->属性获取当前模型字段值的写法是无效的。预加载时只会调用一次关联定义方法生成统一的关联查询SQL,此时$this指向的是临时创建的空模型实例或者首个模型实例,不会逐行匹配每个主记录的字段值,因此出现所有记录的条件都复用第一条属性的问题。

解决方案

方案1:联表查询关联(兼容原有关联定义,实现最简)

修改关联定义,将硬编码的$this->属性替换为SQL表达式引用主表字段,再使用joinWith做联表查询即可:

  1. 调整关联定义:
public function getNext()
{
    return $this->hasOne(self::class, [
        'bd_name' => 'bd_name',
        'uid_client' => 'uid_client',
        'remind_uid_user' => 'remind_uid_user',
    ])
        ->andOnCondition(['or',
            [">", 'next_tab.dt_remind', new \yii\db\Expression('main_tab.dt_remind')],
            ['and', 
                ["=", 'next_tab.dt_remind', new \yii\db\Expression('main_tab.dt_remind')], 
                [">", 'next_tab.tm_remind', new \yii\db\Expression('main_tab.tm_remind')]
            ]
        ])
        ->orderBy(['next_tab.dt_remind' => SORT_ASC, 'next_tab.tm_remind' => SORT_ASC]);
}
  1. 修改查询逻辑,指定表别名后联表查询:
$actions['index']['modifyQuery'] = function(CommentQuery $query) {
    $query->alias('main_tab')->joinWith('next next_tab');
};

注意:该方案为单SQL联表查询,适合中等数据量场景,数据量极大时建议使用方案2。

方案2:手动匹配下一条记录(全数据库兼容,性能最优)

不需要依赖Yii的关联预加载,一次性查出所有记录后在内存中分组匹配,仅执行1次SQL查询,性能远高于框架原生预加载,支持超大数据量:

// 第一步:查询时按分组键、时间排序
$actions['index']['modifyQuery'] = function(CommentQuery $query) {
    $query->orderBy([
        'bd_name' => SORT_ASC, 
        'uid_client' => SORT_ASC, 
        'remind_uid_user' => SORT_ASC, 
        'dt_remind' => SORT_ASC, 
        'tm_remind' => SORT_ASC
    ]);
};

// 第二步:查询出结果后手动绑定next属性
$comments = Comment::find()->...->all();
$grouped = [];
foreach ($comments as $comment) {
    // 按关联键分组
    $key = implode('|', [$comment->bd_name, $comment->uid_client, $comment->remind_uid_user]);
    if (isset($grouped[$key])) {
        // 同组内上一条记录的next指向当前记录
        end($grouped[$key])->next = $comment;
    }
    $grouped[$key][] = $comment;
}

方案3:窗口函数预生成序号(数据库支持MySQL8.0+/MariaDB10.2+时可选)

通过窗口函数提前给同组评论生成排序序号,直接关联序号+1的记录即可,性能介于方案1和方案2之间,适合需要纯SQL实现的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 23:15:05