You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何统计每个分类的订单数量?附相关数据表及Model代码

如何统计每个分类对应的订单数量?

嘿,结合你给出的Yii2模型和数据表结构,我给你分享几个实用的实现方法,你可以按需选择:

1. 用Yii2关联统计(最贴合ActiveRecord的写法)

既然你的Category模型已经定义了和Orders的关联关系getOrders(),那直接用Yii2提供的withCount()方法就能轻松搞定,这也是最推荐的方式:

// 查询所有分类,并附带每个分类的订单数量
$categories = Category::find()
    ->select(['id', 'name']) // 可选:只获取需要的字段,提升性能
    ->withCount('orders') // 统计关联的orders数量,结果会存在`orders_count`属性里
    ->all();

// 遍历输出结果
foreach ($categories as $category) {
    echo "分类:{$category->name},订单数:{$category->orders_count}\n";
}

如果需要过滤订单(比如只统计已处理的订单),可以给withCount传入闭包添加条件:

$categories = Category::find()
    ->withCount(['orders' => function ($query) {
        $query->where(['processed' => 1]); // 只统计processed=1的订单
    }])
    ->all();

2. 原生SQL查询(适合复杂统计或性能优先场景)

如果你的统计逻辑比较复杂,或者想直接用SQL来控制,这种方式更灵活:

$stats = Yii::$app->db->createCommand('
    SELECT c.id, c.name, COUNT(o.id) AS order_count
    FROM category c
    LEFT JOIN orders o ON c.id = o.category_id
    GROUP BY c.id, c.name
')->queryAll();

// 遍历结果(返回的是数组而非模型对象)
foreach ($stats as $item) {
    echo "分类:{$item['name']},订单数:{$item['order_count']}\n";
}

小贴士:用LEFT JOIN会保留所有分类(包括没有订单的,此时order_count为0);如果只需要统计有订单的分类,换成INNER JOIN即可。同样可以添加过滤条件,比如只统计已处理订单:

LEFT JOIN orders o ON c.id = o.category_id AND o.processed = 1

3. Yii2查询构建器实现(兼顾灵活性和ORM风格)

不想写原生SQL但又需要分组统计?可以用查询构建器来实现:

$stats = Category::find()
    ->select([
        'category.id',
        'category.name',
        'COUNT(orders.id) AS order_count'
    ])
    ->leftJoin('orders', 'category.id = orders.category_id')
    ->groupBy(['category.id', 'category.name'])
    ->asArray() // 返回数组结果,不需要模型对象时开启
    ->all();

这样既保留了Yii2的ORM风格,又能灵活控制查询逻辑~

内容的提问来源于stack exchange,提问作者Evgenii Duniak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:04:47