现在的位置: 首页 > 综合 > 正文

yii快速入门教程16

2013年10月29日 ⁄ 综合 ⁄ 共 2143字 ⁄ 字号 评论关闭

7、统计查询
除了上面描述的关联查询,Yii 也支持所谓的统计查询(或聚合查询)。 它指的是检索关联对象的聚合信息,例如每个 post 的评论的数量,每个产品的平均等级等。 统计查询只被 HAS_MANY(例如,一个 post 有很多评论) 或 MANY_MANY (例如,一个 post 属于很多分类和一个 category 有很多 post) 关联对象执行。
执行统计查询非常类似于之前描述的关联查询。我们首先需要在 CActiveRecord 的 relations() 方法中声明统计查询。
class Post extends CActiveRecord

{
    public function relations()
   {
        return array(

            'commentCount'=>array(self::STAT,
'Comment', 'post_id'),

            'categoryCount'=>array(self::STAT,
'Category', 'post_category(post_id,

category_id)'),
        );
    }
}
在上面,我们声明了两个统计查询:commentCount 计算属于一个 post 的评论的数量,categoryCount 计算一个 post 所属分类的数量。注意 Post 和 Comment 之间的关联类型是 HAS_MANY, 而 Post 和 Category 之间的关联类型是 MANY_MANY (使用连接表 PostCategory)。 如我们所看到的,声明非常类似于之间小节中的关联。唯一的不同是这里的关联类型是 STAT。
有了上面的声明,我们可以检索使用表达式 $post->commentCount 检索一个 post 的评论的数量。 当我们首次访问此属性,一个 SQL 语句将被隐含地执行并检索 对应的结果。我们已经知道,这是所谓的 lazy loading 方法。若我们需要得到多个post 的评论数目,我们也可以使用 eager loading 方法:
$posts=Post::model()->with('commentCount', 'categoryCount')->findAll();
上面的语句将执行三个 SQL 语句以取回所有的 post 及它们的评论数目和分类数目。使用延迟加载方法, 若有 N 个 post ,我们使用 2*N+1 条 SQL 查询完成。
默认情况下,一个统计查询将计算 COUNT 表达式(and thus the comment count and category count in the above example). 当我们在 relations()中声明它时,通过 指定额外的选项,可以定制它。可用的选项简介如下。
select: 统计表达式。默认是 COUNT(*),意味着子对象的个数。
defaultValue: 没有接收一个统计查询结果时被赋予的值。例如,若一个 post 没有任何评论,它的 commentCount 将接收此值。此选项的默认值是 0。
condition: WHERE 子语句。默认是空。
params: 被绑定到产生的SQL 语句中的参数。它应当是一个 name-value 对组成的数组。
order: ORDER BY 子语句。默认是空。
group: GROUP BY 子语句。默认是空。
having: HAVING 子语句。默认是空。
8、关联查询命名空间
关联查询也可以和 命名空间一起执行。有两种形式。第一种形式,命名空间被应用到主模型。第二种形式,命名空间被应用到关联模型。
下面的代码展示了如何应用命名空间到主模型。
$posts=Post::model()->published()->recently()->with('comments')->findAll();
这非常类似于非关联的查询。唯一的不同是我们在命名空间后使用了 with() 调用。 此查询应当返回最近发布的 post和它们的评论。
下面的代码展示了如何应用命名空间到关联模型。
$posts=Post::model()->with('comments:recently:approved')->findAll();
上面的查询将返回所有的 post 及它们审核后的评论。注意 comments 指的是关联名字,而 recently 和 approved 指的是 在 Comment 模型类中声明的命名空间。关联名字和命名空间应当由冒号分隔。
命名空间也可以在 CActiveRecord::relations() 中声明的关联规则的 with 选项中指定。在下面的例子中, 若我们访问 $user->posts,它将返回此post 的所有审核后的评论。
class User extends CActiveRecord
{
    public function relations()

    {
        return array(
            'posts'=>array(self::HAS_MANY,
'Post', 'author_id',

                'with'=>'comments:approved'),
        );
    }

}
注意: 应用到关联模型的命名空间必须在 CActiveRecord::scopes 中指定。结果,它们不能被参数化。

抱歉!评论已关闭.