首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

Yii Framework 關聯查詢統計功能(STAT)詳解

     編輯:PHP 相關知識

什麼是統計查詢(STAT)?

在 CActiveRecord::relations() 中聲明 self::STAT 類型關聯,用於獲取關聯對象的**聚合信息**(計數、求和、平均值等),而非具體記錄。

適用關係:HAS_MANY、MANY_MANY。

聲明統計關聯

class Post extends CActiveRecord {
    public function relations() {
        return [
            // 評論數:Post HAS_MANY Comment (post_id)
            'commentCount' => [self::STAT, 'Comment', 'post_id'],

            // 分類數:Post MANY_MANY Category 通過中間表 post_category
            'categoryCount' => [self::STAT, 'Category', 'post_category(post_id, category_id)'],

            // 進階:指定聚合表達式(Yii 1.1.14+)
            'totalViews' => [self::STAT, 'PostView', 'post_id', 'select' => 'SUM(views)'],
            'avgRating'  => [self::STAT, 'Rating', 'post_id', 'select' => 'AVG(score)'],
        ];
    }
}

使用方式

延遲加載(按需查詢)

$post = Post::model()->findByPk(1);
echo $post->commentCount;    // 自動執行 SELECT COUNT(*) FROM comment WHERE post_id=1
echo $post->categoryCount;   // 自動執行關聯表 COUNT 查詢

急切加載(with() 一次查詢)

$posts = Post::model()->with('commentCount', 'categoryCount')->findAll();
foreach ($posts as $post) {
    echo $post->title . ': ' . $post->commentCount . ' 條評論';
}
// 僅執行 3 條 SQL:主查詢 + 兩條統計子查詢(JOIN 或子查詢)

命名範圍結合統計查詢

主模型應用範圍

$posts = Post::model()->published()->recently()->with('comments')->findAll();

關聯模型應用範圍

$posts = Post::model()->with('comments:recently:approved')->findAll();
// comments 關聯應用 recently 和 approved 兩個命名範圍

在 relations() 中預設綁定範圍

class User extends CActiveRecord {
    public function relations() {
        return [
            'posts' => [self::HAS_MANY, 'Post', 'author_id', 'with' => 'comments:approved'],
        ];
    }
}
// $user->posts 直接包含已審核評論

進階技巧

自定義 SELECT 表達式

'commentCount' => [
    self::STAT, 'Comment', 'post_id',
    'select' => 'COUNT(DISTINCT user_id)'  // 統計不同用戶評論數
],

條件過濾

'approvedCommentCount' => [
    self::STAT, 'Comment', 'post_id',
    'condition' => 'status=1'  // 僅統計通過審核的評論
],

默認範圍影響統計

若關聯模型定義了 defaultScope(),統計查詢**會自動應用**該範圍。如需忽略,可在統計關聯中設置 'defaultScope' => false(Yii 1.1.13+)。

性能優化建議

  • **列表頁必用 with() 急切加載**,避免 N+1 問題。
  • 大數據量時,考慮**反範式化**:在主表添加 comment_count 欄位,寫入時同步更新(觸發器/應用層),讀取時零查詢開銷。
  • 統計查詢產生的 SQL 通常為 SELECT COUNT(*) ...,確保關聯外鍵欄位有**索引**。

常見誤區

  • STAT 不能用於 BELONGS_TO / HAS_ONE:這兩種關係本質是單記錄,無聚合意義。
  • 統計結果會被緩存:同一請求內多次訪問 $post->commentCount 只查詢一次;跨請求需自行緩存(Redis/Memcached)。
  • 關聯名不能與表字段重名:否則 $post->commentCount 會覆蓋字段值。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved