Yii Framework 2.0从左表中获取数据,该数据在右侧tabke中不作为外键存在

时间:2014-12-19 11:04:54

标签: php relational-database yii2 jointable

使用Yii framework 2.0,我有两个数据库表(A和B)。它是一个关系数据库1:n。 A只有一个B,但B有很多A.我的数据库看起来与此类似。

A table:
  id = 1, name = yes
  id = 2, name = no
  id = 3, name = ok
  id = 4, name = good

B table:
  id = 1, a_id = 1
  id = 2, a_id = 1
  id = 3, a_id = 2

我想从' A'中检索记录。其主键未出现在' B'表。我想得到的结果是。

A table:
  id = 3, name = ok
  id = 4, name = good

我不想使用以下代码,因为它对我来说效率不高。

$allA = A::find()->all();   

foreach($allA as $model) {

     if(!$model->getBs()) {
         $allAWithoutB[] = $model;
     }

}     

如何定义这样的关系方法或范围BQuery类,以便我不需要查询所有A记录并在for-each循环中过滤它们?

2 个答案:

答案 0 :(得分:1)

我认为这种逻辑不适合关系。

您可以将查询与子查询一起使用。首先从a_id表中选择所有唯一b,然后从a表中选择中将其排除。将此方法放在AModel

public function getOtherModels()
{
    $subquery = BModel::find()->select('a_id')->distinct()->all();

    return static::find()->where(['not in', 'id', $subquery]);
}

如果您愿意,可以将其放在scope中。

答案 1 :(得分:1)

arogachev发布的答案几乎正确。

如果您要运行他的方法getOtherModels(),您将获得“无法将对象转换为字符串”#39;异常。

我的方法完全相同,除了我已经使用方法static并添加了foreach来遍历对象并将a_id值添加到新数组中。 / p>

我还在方法中添加了$condition参数,因此您可以为A模型添加条件。

/**
 * @return \yii\db\ActiveQuery
 */
public static function withoutBModel($condition = null)
{
    $subquery = BModel::find()->select('a_id')->distinct()->all();
    $arr = [];
    foreach ($subquery as $q) {
        $arr[] = $q->a_id;
    }
    $query = static::find()->where(['not in', 'id', $arr]);
    if (!empty($condition)) {
        $query->andWhere($condition);
    }
    return $query;
}

使用此方法如下:

$aModelsWithoutB = A::withoutBModel('active = 1')->all();