Если вы хотите найти сообщения со всеми тремя тегами, вам нужно создать запрос с тройным объединением - по одному объединению для каждого тега. Предполагая, что у вас есть отношение тегов, определенное как:
public function getTags() {
return $this->hasMany(Tag::class, ['id' => 'tag_id'])
->viaTable('{{%posts_tags}}', ['post_id' => 'id']);
}
Вы должны быть в состоянии получить то, что вы хотите:
$posts = Post::find()
->innerJoinWith('tags as tags1', false)
->andWhere(['tags1.name' => 'A'])
->innerJoinWith('tags as tags2', false)
->andWhere(['tags2.name' => 'B'])
->innerJoinWith('tags as tags3', false)
->andWhere(['tags3.name' => 'C'])
->all();
В качестве альтернативы вы можете использовать COUNT()
с GROUP BY
и подсчитывать количество совпадающих тегов, но это будет ненадежно, если вы разрешите присваивать один тег несколько раз одному сообщению.
$posts = Post::find()
->innerJoinWith('tags', false)
->andWhere(['tags.name' => ['A', 'B', 'C']])
->groupBy('posts.id')
->having('COUNT(*) >= 3')
->all();