YII - 加载所有 has_many 记录接受条件的所有父记录

YII - Load all parent records where all has_many records accepts a condition

在下面的代码中,这将加载所有作者的一篇帖子 post.title = 'search'

// query criteria
$criteria = new CDbCriteria();
// with Post model
$criteria->with = array('posts');
// compare title
$criteria->compare('posts.title', $searchWord, true);
// find all authors
$authors = Author::model()->findAll($criteria);
// show all authors and his/her posts
foreach($authors as $author)
{
    echo "Author = " . $author->name . "\n";
    foreach($author->posts as $post)
    {
        echo "Post = " . $post->title . "\n";
    }
}

但我需要的只是加载那些所有帖子都接受条件的作者。我在这里使用分页,所以我想做一个查找语句。

我在这上面浏览了很多,但能找到的是 HAS_MANY 记录的预加载和延迟加载,但我需要的是不同的。

有人可以帮忙吗?

该解决方案要求您查询符合 post 标准的作者,然后检查这些作者是否没有任何 post 不满足标准。

简单来说sql,意思是这样的

select * from author where id in (select author from post where post.title like '%word%') and id not in (select author from post where postcriteria not like '%word%')

在 Yii 中实现这个需要 db query ,示例查询是

Yii::app()->db->createCommand()
->select('*')
->from('author') 
->where('id in (select author from post where post.title like %:word%) 
 and id not in (select author from post where post.title not like %:word%)', array(':word'=>$word))
->queryRow();

按帖子搜索而不是按作者搜索怎么样?

// query criteria
$criteria = new CDbCriteria();
// with author model
$criteria->rightJoin('author', 'author.id=post.author_id')
// compare title
$criteria->compare('title', $searchWord, true);

//optional: group by author
$criteria->group = 'author.id';

// find all posts
$posts = Post::model()->findAll($criteria);

// show all post with theirs author
foreach($posts as $post)
{
    echo "Post = " . $post->title . "\n";
    echo "Author = " . $post->author->name .  "\n";
}

这将为作者提供满足条件的所有帖子

// query criteria
$criteria = new CDbCriteria();
// with Post model
$criteria->with = array('posts');
// compare title
$criteria->compare('posts.title', $searchWord, true);

$criteria->select = ['*',new CDbExpression('(SELECT COUNT(id) FROM posts WHERE author_id = t.id) AS all_posts'),new CDbExpression('COUNT(posts.id) AS post_count')];

$criteria->group = 't.id';

$criteria->distinct = true;

$criteria->having = 'all_posts = post_count';

// find all authors
$authors = Author::model()->findAll($criteria);
// show all authors and his/her posts
foreach($authors as $author)
{
    echo "Author = " . $author->name . "\n";
    foreach($author->posts as $post)
    {
        echo "Post = " . $post->title . "\n";
    }
}