Yii Framework 2.0 получает данные из левой таблицы, которая не существует как внешний ключ в правой вкладке

Работая с 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?

1

Решение

Ответ, который опубликовал арогачев, почти правильный.

Если бы вы должны были запустить его метод getOtherModels() вы получите исключение «Невозможно преобразовать объект в строку».

Мой метод ниже делает то же самое, за исключением того, что я сделал метод static и добавил foreach перебрать объекты и добавить a_id значения в новый массив.

Я также добавил $condition аргумент метода, так что вы можете добавить условия для моделей А.

/**
* @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();
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]);
}

Вы можете положить это в объем если ты хочешь.

1

По вопросам рекламы [email protected]