count、max、min、avg、sum 五种聚合方法可直连数据库高效运算,但需严格遵循字段名传参规则(count除外)、前置where条件、避免group中使用函数等限制,否则易出错或返回异常值。

count、max、min、avg、sum 这五个方法能直接走数据库聚合,不拉全量数据,性能好、语义清——但它们不是万能的,用错参数或混搭连贯操作,很容易查出空值、0 或 SQL 报错。
统计方法必须传字段名,count 是唯一例外
除 count 外,max、min、avg、sum 全部强制要求传字段名,漏写或传错会直接报错或返回 null。
-
count()不传参 = 统计行数(COUNT(*)),传"id"= 统计非 NULL 的 id 行数(COUNT(id)) -
max("score")合法,max()或max("user_id, score")都非法 - 字段名必须是真实存在的列,别名、表达式、函数调用(如
DATE(create_time))不能直接塞进这些方法里 - 如果字段可能为 NULL,
avg和sum会自动忽略,但count("field")也会跳过 NULL —— 要总数请用count()
where 条件必须在聚合前链式调用
ThinkPHP 的聚合方法不接受独立条件参数,所有筛选都得靠 where + 连贯操作前置完成。
- ✅ 正确:
$User->where('status', 1)->count() - ❌ 错误:
$User->count(['status' => 1])(语法不支持) - ⚠️ 注意:模糊查询要自己补
%,where('name', 'like', '%admin%')才生效;写成'admin'就是等值匹配 - ⚠️
IN查询必须传数组:where('id', 'in', [1,2,3]),传字符串'1,2,3'会被当单个字符串处理 - 判断 NULL 得用
whereNull('email'),where('email', null)生成的是= NULL,MySQL 永远返回 false
按日期分组聚合?group() 不认 DATE() 表达式
想按天/月统计注册用户数?别在 group('DATE(create_time)') 里硬塞函数 —— ThinkPHP 会对 group() 参数做字段白名单校验,直接报错或分组失效。
- ✅ 推荐方案:用
field()先定义别名,再group别名$User->field('COUNT(*) as cnt, DATE(create_time) as day')->group('day')->select() - ✅ 更灵活方案:改用
Db::query()写原生 SQL,可控性强Db::query("SELECT COUNT(*), DATE(create_time) FROM user GROUP BY DATE(create_time)") - ⚠️
group()只接受纯字段名或已定义的别名,不解析函数、不转义表达式 - 注意时区:
DATE(create_time)依赖 MySQL 服务端时区,和 PHP 时区不一致时结果可能偏移一天
find() 和 select() 返回值类型影响聚合结果取值
聚合方法本身返回标量(整数、浮点数、null),但很多人把它和查询方法混淆,导致取值逻辑出错。
立即学习“PHP免费学习笔记(深入)”;
-
count()返回int,但如果你写成$User->where(...)->count()->toArray(),会报错 —— 它不是对象,没有toArray()方法 -
select()返回Collection,哪怕只有一条记录;find()返回数组或null,不是集合 - 聚合结果不要用
empty()直接判空:count()返回 0 是合法结果,is_null($res)才能区分“查不到”和“确实为 0” - 多字段聚合(比如同时要
count和avg)必须用field()+select(),单个聚合方法一次只能算一个指标
group() 对函数表达式的限制,是线上最容易踩坑的点。



















