yii快速入门教程16、绝对适合初学 [ 技术分享 ]
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 ,我们使用 2N+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 中指定。结果,它们不能被参数化。
共 0 条回复
lz19881123 深圳
最后登录:2019-05-26
在线时长:7小时52分
- 粉丝37
- 金钱1030
- 威望0
- 积分1100