CodeIgniter中实现分组统计需用group_by()配合聚合函数,SELECT非聚合字段须全在GROUP BY中,WHERE用于分组前过滤,HAVING用于分组后过滤且须在group_by()后、get()前。

CodeIgniter 中实现分组统计(GROUP BY)查询,核心是使用 Query Builder 的 group_by() 方法配合聚合函数(如 count()、sum()、avg() 等),同时注意避免常见陷阱(如 SELECT 字段与 GROUP BY 不一致导致报错)。
基础分组统计写法
最常用场景:按某字段分组并统计每组数量。例如统计各分类下的文章数:
- 使用 $this->db->select('category, COUNT(*) as total') 明确指定分组字段和聚合结果
- 调用 $this->db->from('articles') 设置数据表
- 用 $this->db->group_by('category') 声明分组依据
- 执行 $query = $this->db->get() 获取结果
多字段分组与复合聚合
支持按多个字段联合分组,也支持多种聚合函数混用。例如按年份和状态统计订单总数与总金额:
- $this->db->select('YEAR(created_at) as year, status, COUNT(*) as cnt, SUM(amount) as total_amount')
- $this->db->group_by('YEAR(created_at), status') —— 多字段用逗号分隔,顺序无关但需与 SELECT 中非聚合字段一致
- 若数据库严格模式开启(如 MySQL 5.7+ ONLY_FULL_GROUP_BY),SELECT 中所有非聚合字段都必须出现在 GROUP BY 中
结合 WHERE 和 HAVING 过滤
WHERE 在分组前筛选原始数据,HAVING 在分组后筛选聚合结果:
- $this->db->where('status', 'active') 可先过滤有效记录
- $this->db->having('cnt > 5') 或 $this->db->having('SUM(amount) >= 1000') 对分组结果做条件限制
- HAVING 必须写在 group_by() 之后、get() 之前,且字段名需与 select 中别名一致
原生 SQL 补充方案
当 Query Builder 难以表达复杂逻辑(如嵌套分组、窗口函数),可安全使用原生查询:
- $sql = "SELECT category, COUNT(*) as total FROM articles WHERE deleted = 0 GROUP BY category HAVING total > 1";
- $query = $this->db->query($sql);
- 注意对变量使用 $this->db->escape() 或绑定参数防止注入,例如:$this->db->query("SELECT * FROM table WHERE id = ?", [$id])

















