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

In the below code this will load all author with one of its posts that has 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 . "
";
    foreach($author->posts as $post)
    {
        echo "Post = " . $post->title . "
";
    }
}

But what I need is only load those authors whose all posts accepts the condition. I am using pagination here so I would like to do it one find statement.

I browsed a lot on this but what can find is eager loading and lazy loading of HAS_MANY records but what I need is different.

Can anyone help on this please?

This will provide authors with all posts satisfying the condition

// 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 . "
";
    foreach($author->posts as $post)
    {
        echo "Post = " . $post->title . "
";
    }
}

The solution requires you to query for authors with required post criteria and then check if those authors do not have any the post not satisfying the criteria.

In simple sql, that would mean something like this

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%')

Implementing this in Yii requires db query , example query would be

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();

What about searching by posts and not by authors?

// 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 . "
";
    echo "Author = " . $post->author->name .  "
";
}