跳到主要内容
版本:2.0.x

聚合函数

你可以使用 group_by 方法对结果进行分组。如果希望进一步限制分组结果集,可以应用 having 方法。

信息

包括 maxminsumavgcount 在内的聚合函数可在 ColumnTrait 中使用。

求和

对单列求和

let sum_order_total: Decimal = order::Entity::find()
.select_only()
.column_as(order::Column::Total.sum(), "sum")
.into_tuple()
.one(db)
.await?
.unwrap();

带分组的求和

let (customer, total_spent): (String, Decimal) = customer::Entity::find()
.left_join(order::Entity)
.select_only()
.column(customer::Column::Name)
.column_as(order::Column::Total.sum(), "sum")
.group_by(customer::Column::Name)
.into_tuple()
.one(db)
.await?
.unwrap();

assert_eq!(customer, "Kate");
assert_eq!(total_spent, 25.into());

分组

group_by 方法可以接受 Entity 的列或复杂的 sea_query::SimpleExpr

assert_eq!(
cake::Entity::find()
.select_only()
.column(cake::Column::Name)
.group_by(cake::Column::Name)
.build(DbBackend::Postgres)
.to_string(),
r#"SELECT "cake"."name" FROM "cake" GROUP BY "cake"."name""#
);

assert_eq!(
cake::Entity::find()
.select_only()
.column_as(cake::Column::Id.count(), "count")
.column_as(cake::Column::Id.sum(), "sum_of_id")
.group_by(cake::Column::Name)
.build(DbBackend::Postgres)
.to_string(),
r#"SELECT COUNT("cake"."id") AS "count", SUM("cake"."id") AS "sum_of_id" FROM "cake" GROUP BY "cake"."name""#
);

将分组与聚合函数结合使用

#[derive(Debug, FromQueryResult)]
struct SelectResult {
name: String,
num_orders: i64,
total_spent: Decimal,
min_spent: Decimal,
max_spent: Decimal,
}

let select = customer::Entity::find()
.left_join(order::Entity)
.select_only()
.column(customer::Column::Name)
.column_as(order::Column::Total.count(), "num_orders")
.column_as(order::Column::Total.sum(), "total_spent")
.column_as(order::Column::Total.min(), "min_spent")
.column_as(order::Column::Total.max(), "max_spent")
.order_by_asc(customer::Column::Name)
.group_by(customer::Column::Name);

let result: Option<SelectResult> = select
.into_model()
.one(&ctx.db)
.await?;

Having 条件

having 方法可以接受前一节介绍的任何条件表达式。

assert_eq!(
cake::Entity::find()
.having(cake::Column::Id.eq(4))
.having(cake::Column::Id.eq(5))
.build(DbBackend::MySql)
.to_string(),
"SELECT `cake`.`id`, `cake`.`name` FROM `cake` HAVING `cake`.`id` = 4 AND `cake`.`id` = 5"
);

assert_eq!(
cake::Entity::find()
.select_only()
.column_as(cake::Column::Id.count(), "count")
.column_as(cake::Column::Id.sum(), "sum_of_id")
.group_by(cake::Column::Name)
.having(Expr::col("count").gt(6))
.build(DbBackend::MySql)
.to_string(),
"SELECT COUNT(`cake`.`id`) AS `count`, SUM(`cake`.`id`) AS `sum_of_id` FROM `cake` GROUP BY `cake`.`name` HAVING `count` > 6"
);