4.3.5 如何统计数据——聚合函数:COUNT/SUM/AVG/MAX/MIN
一句话破题
聚合函数把多行数据"压缩"成一个值——统计数量、求和、平均值等都靠它。
五大聚合函数
| 函数 | 作用 | 示例 |
|---|---|---|
| COUNT | 计数 | 文章总数 |
| SUM | 求和 | 订单总金额 |
| AVG | 平均值 | 平均评分 |
| MAX | 最大值 | 最高价格 |
| MIN | 最小值 | 最低价格 |
基础用法
COUNT:计数
sql
-- 统计用户总数
SELECT COUNT(*) FROM users;
-- 统计有邮箱的用户数(不计 NULL)
SELECT COUNT(email) FROM users;
-- 统计不重复的城市数
SELECT COUNT(DISTINCT city) FROM users;SUM:求和
sql
-- 订单总金额
SELECT SUM(amount) FROM orders;
-- 某用户的订单总金额
SELECT SUM(amount) FROM orders WHERE user_id = 'xxx';AVG:平均值
sql
-- 平均订单金额
SELECT AVG(amount) FROM orders;
-- 平均评分
SELECT AVG(rating) FROM reviews WHERE product_id = 'xxx';MAX / MIN:最大最小值
sql
-- 最高和最低价格
SELECT MAX(price), MIN(price) FROM products;
-- 最新订单时间
SELECT MAX(created_at) FROM orders;GROUP BY:分组聚合
按分组统计:
sql
-- 每个用户的订单数
SELECT user_id, COUNT(*) as order_count
FROM orders
GROUP BY user_id;
-- 每个分类的商品数和平均价格
SELECT category_id, COUNT(*) as count, AVG(price) as avg_price
FROM products
GROUP BY category_id;HAVING:过滤分组结果
sql
-- 订单数超过 10 的用户
SELECT user_id, COUNT(*) as order_count
FROM orders
GROUP BY user_id
HAVING COUNT(*) > 10;WHERE vs HAVING:
- WHERE:过滤原始行(分组前)
- HAVING:过滤聚合结果(分组后)
sql
-- WHERE 过滤单价 > 100 的订单
-- HAVING 过滤总金额 > 1000 的用户
SELECT user_id, SUM(amount) as total
FROM orders
WHERE amount > 100
GROUP BY user_id
HAVING SUM(amount) > 1000;Prisma 中的聚合
基础聚合:
typescript
// 统计用户总数
const count = await prisma.user.count()
// 条件统计
const activeCount = await prisma.user.count({
where: { status: 'ACTIVE' }
})聚合函数:
typescript
const result = await prisma.order.aggregate({
_count: true,
_sum: { amount: true },
_avg: { amount: true },
_max: { amount: true },
_min: { amount: true }
})
// { _count: 100, _sum: { amount: 50000 }, _avg: { amount: 500 }, ... }分组聚合:
typescript
// 按用户分组统计订单
const result = await prisma.order.groupBy({
by: ['userId'],
_count: true,
_sum: { amount: true }
})
// [{ userId: 'u1', _count: 5, _sum: { amount: 1000 } }, ...]分组过滤(having):
typescript
const result = await prisma.order.groupBy({
by: ['userId'],
_count: true,
having: {
amount: {
_sum: { gt: 1000 } // 总金额 > 1000
}
}
})常见统计场景
场景一:用户统计面板
typescript
const stats = await prisma.$transaction([
prisma.user.count(),
prisma.user.count({ where: { status: 'ACTIVE' } }),
prisma.order.aggregate({ _sum: { amount: true } })
])场景二:排行榜
typescript
const topSellers = await prisma.order.groupBy({
by: ['productId'],
_count: true,
orderBy: { _count: { productId: 'desc' } },
take: 10
})本节小结
- 聚合函数把多行数据汇总成一个值
- COUNT/SUM/AVG/MAX/MIN 是五大聚合函数
- GROUP BY 按字段分组统计
- HAVING 过滤分组结果
- Prisma 提供
count()、aggregate()、groupBy()方法
