聚合函数
Orchid ORM 支持丰富的聚合函数(如 count、min、max、string_agg 等),并允许调用自定义聚合函数。每个聚合函数均支持以下配置选项:
type AggregateOptions = {
distinct?: boolean; // 添加 DISTINCT 修饰符
order?: OrderArg | OrderArg[]; // 排序参数(等效于 .order())
filter?: WhereArg; // 过滤条件(等效于 .where())
filterOr?: WhereArg[]; // OR 逻辑过滤条件(等效于 .orWhere())
withinGroup?: boolean; // 添加 WITHIN GROUP 子句
over?: WindowName | OverOptions; // 定义 OVER 子句(窗口函数)
};
基础用法
-
直接调用:在表实例上直接调用聚合函数,返回单一统计值:
const totalRecords: number = await db.table.count(); // 统计总记录数 -
在 select 中使用:在
select回调中调用聚合函数,返回包含统计值的对象数组:const stats = await db.table.select({ count: (q) => q.count(), // 记录数 avgPrice: (q) => q.avg('price'), // 价格平均值(可能为 null) }); -
在 having 中过滤:结合
having子句对分组结果进行筛选:db.table.group('category').having((q) => q.count().gte(10)); // 筛选记录数 ≥10 的分组
类型安全与链式操作
聚合函数支持与列操作符链式调用,严格遵循返回类型约束:
// 数值型聚合函数支持数值比较(如 gt、lt)
const hasHighSum = await db.table.sum('sales').gt(1000);
// 字符串聚合函数支持文本匹配(如 contains)
const hasKeyword = await db.table.stringAgg('tags').contains('featured');
// 布尔聚合函数支持逻辑操作(如 not)
const allInactive = await db.table.boolAnd('isActive').not(true);
组合多个聚合条件
通过 and/or 操作符组合多个聚合结果:
// 同时满足记录数 >5 且总和 <100
const isValid = await db.table
.count().gt(5)
.and(db.table.sum('quantity').lt(100));
// 在 select 中组合条件
const { isValid } = await db.table.select({
isValid: (q) => q.count().gt(5).and(q.sum('quantity').lt(100)),
});
内置聚合函数详解
count
功能:统计记录数或非空列值数量
const total = await db.table.count(); // 统计所有记录
const nonNullNames = await db.table.count('name'); // 统计 name 非空的记录
const groupedCounts = await db.people
.select('city', { population: (q) => q.count() })
.group('city'); // 按城市分组统计人口
min/max
功能:获取数值列的最小值 / 最大值(无记录时返回 null)
const lowestPrice = await db.product.min('price'); // 最低价格
const highestScoreByCategory = await db.product
.select('category', { maxScore: (q) => q.max('score') })
.group('category'); // 按类别分组的最高分数
sum/avg
功能:计算数值列总和 / 平均值(无记录时返回 null)
const totalSales = await db.orders.sum('amount'); // 总销售额
const avgRating = await db.movie.avg('rating'); // 平均评分
bitAnd/bitOr
功能:按位与 / 或聚合(返回数值或 null)
const combinedFlags = await db.flags.bitAnd('flag'); // 按位与聚合标志位
boolAnd/boolOr/every
功能:布尔值逻辑与 / 或聚合(every 等同于 boolAnd)
const allActive = await db.users.boolAnd('isActive'); // 所有用户是否均激活
const anyPending = await db.tasks.boolOr('isPending'); // 是否存在待处理任务
jsonAgg/jsonbAgg
功能:聚合值为 JSON 数组(jsonbAgg 适用于 JSON 操作场景)
const userIds = await db.users.jsonAgg('id'); // 聚合用户 ID 数组
const groupedTags = await db.posts
.select('category', { tags: (q) => q.jsonbAgg('tags') })
.group('category'); // 按类别分组的标签数组
jsonObjectAgg/jsonbObjectAgg
功能:构造 JSON 对象(键为字符串,值为列或 SQL 表达式)
const userProfile = await db.users.jsonObjectAgg({
username: 'name', // 列名映射
fullName: sql`CONCAT(first_name, ' ', last_name)`, // 原始 SQL 表达式
}); // 返回 { username: string, fullName: string } | null
stringAgg
功能:连接字符串(支持分隔符参数)
const commaNames = await db.students.stringAgg('name', ', '); // 逗号分隔的姓名列表
const groupedEmails = await db.clients
.select('department', { emails: (q) => q.stringAgg('email', '; ') })
.group('department'); // 按部门分组的邮箱列表
xmlAgg
功能:连接 XML 列内容
const combinedXml = await db.records.xmlAgg('content'); // 合并 XML 内容