首页 文章

SELECT中的子查询使用Yii2 ActiveRecord

提问于
浏览
2

是否可以在Yii2中将此类SQL转换为ActiveRecord查询:

SELECT 
*,
(select count(*) from pendaftar where pendaftar.prodi_pilihan_1 =  a.id_prodi_penerima)as jum1,
(select count(*) from pendaftar where pendaftar.prodi_pilihan_2 = a.id_prodi_penerima)as jum2 
FROM prodi_penerima as a

我有两个关系模型 PendaftarProdiPenerima .

这是 Pendaftar 型号:

...
* @property ProdiPenerima $prodiPilihan1
* @property ProdiPenerima $prodiPilihan2
...
/**
 * @return \yii\db\ActiveQuery
 */
public function getPekerjaanIdPekerjaan()
{
    return $this->hasOne(Pekerjaan::className(), ['id_pekerjaan' => 'pekerjaan_id_pekerjaan']);
}

/**
 * @return \yii\db\ActiveQuery
 */
public function getUserPendaftar()
{
    return $this->hasOne(User::className(), ['id' => 'id_user_pendaftar']);
}

/**
 * @return \yii\db\ActiveQuery
 */
public function getProdiPilihan1()
{
    return $this->hasOne(ProdiPenerima::className(), ['id_prodi_penerima' => 'prodi_pilihan_1']);
}
/**
 * @return \yii\db\ActiveQuery
 */
public function getProdiPilihan2()
{
    return $this->hasOne(ProdiPenerima::className(), ['id_prodi_penerima' => 'prodi_pilihan_2']);
}

这是 ProdiPenerima 型号:

...
* @property Pendaftar[] $pendaftars
* @property Pendaftar[] $pendaftars0
...
/**
 * @return \yii\db\ActiveQuery
 */
public function getPendaftars()
{
    return $this->hasMany(Pendaftar::className(), ['prodi_pilihan_1' => 'id_prodi_penerima']);
}

/**
 * @return \yii\db\ActiveQuery
 */
public function getPendaftars0()
{
    return $this->hasMany(Pendaftar::className(), ['prodi_pilihan_2' => 'id_prodi_penerima']);
}

prodi_pilihan_1prody_pilihan_2pendaftar 表中的外键,该键是从 ProdiPenerima 表引用的 .

1 回答

  • 5
    $result = ProdiPenerima::find()
        ->select([
            '*',
            'jum1' => Pendaftar::find()
                ->select(['COUNT(*)'])
                ->where('pendaftar.prodi_pilihan_1 = a.id_prodi_penerima'),
            'jum2' => Pendaftar::find()
                ->select(['COUNT(*)'])
                ->where('pendaftar.prodi_pilihan_2 = a.id_prodi_penerima')
        ])
        ->alias('a')
        ->asArray()
        ->all();
    

    结果可通过以下方式访问:

    foreach ($result as $row) { 
        echo $row['jum1']; 
    }
    

    那是因为使用了asArray(),所以查询返回数组的数组而不是模型数组 .


    如果需要模型,则应在模型中添加属性以存储子查询的结果:

    class ProdiPenerima extends ActiveRecord {
    
        public $jum1;
        public $jum2;
    
        // ...
    }
    

    然后从查询中删除 isArray()

    $result = ProdiPenerima::find()
        ->select([
            '*',
            'jum1' => Pendaftar::find()
                ->select(['COUNT(*)'])
                ->where('pendaftar.prodi_pilihan_1 = a.id_prodi_penerima'),
            'jum2' => Pendaftar::find()
                ->select(['COUNT(*)'])
                ->where('pendaftar.prodi_pilihan_2 = a.id_prodi_penerima')
        ])
        ->alias('a')
        // ->asArray()
        ->all();
    

    结果可通过以下方式访问:

    foreach ($result as $model) { 
        echo $model->jum1; 
    }
    

    但请注意,使用 asArray() 会更快,因此除非您需要访问某些模型方法(或依赖于对数据库的值进行类型转换),否则我更喜欢数组 .

相关问题