如何统计每个分类的订单数量?附相关数据表及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
相关产品推荐
相关产品推荐

