⚠️ Alpha内测版本警告:此为早期内部构建版本,尚不完整且可能存在错误,欢迎大家提Issue反馈问题或建议
Skip to content

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() 方法