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

如何在Yii2中用ActiveRecord写法实现指定原生SQL查询

嘿,我来帮你把这段原生SQL转换成Yii2 ActiveRecord的写法,其实很直观,咱们分两种常用的方式来实现:

方式一:直接使用leftJoin(无需额外定义模型关联)

这种方式适合不想额外配置模型关联的场景,手动指定关联条件即可:

// 因为是根据country_id查询单条记录,用one()比all()更合理哦
$priceData = \backend\models\Price::find()
    ->select([
        'basic' => 'p.basic_plan_amt',
        'premium' => 'p.premium_plan_amt',
        'daju' => 'p.daju_plan_amt',
        'country' => 'c.name'
    ])
    // 第一个参数是表名+别名,第二个是关联匹配条件
    ->leftJoin('country c', 'p.country_id = c.id')
    // 数组形式的where会自动做参数绑定,彻底避免SQL注入风险
    ->where(['p.country_id' => $country_id])
    ->one();

方式二:使用joinWith(推荐,符合ActiveRecord设计理念)

如果你的Price模型还没定义和Country的关联,先在backend\models\Price.php里添加关联方法:

public function getCountry()
{
    // 关联Country模型,匹配规则:Price.country_id = Country.id
    return $this->hasOne(\backend\models\Country::className(), ['id' => 'country_id']);
}

之后就可以用更简洁的joinWith语法查询了:

$priceData = \backend\models\Price::find()
    ->select([
        'basic' => 'price.basic_plan_amt',
        'premium' => 'price.premium_plan_amt',
        'daju' => 'price.daju_plan_amt',
        'country' => 'country.name'
    ])
    // 直接调用关联方法名,框架自动处理关联逻辑
    ->joinWith(['country'])
    ->where(['price.country_id' => $country_id])
    ->one();

小提示

  • 原原生SQL直接拼接$country_id存在SQL注入风险,而ActiveRecord的where数组写法会自动做参数绑定,安全系数更高;
  • 如果你确定查询结果只有一条,用one()比all()更高效,返回的是单个模型对象(或null);如果确实可能有多条匹配记录,再换成all()即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 14:12:32