SqlSugar是一个轻量级但功能强大的.NET ORM框架,它提供了丰富的查询功能,包括灵活的分组查询操作。分组查询是数据库操作中常见的需求之一,用于将数据集合按照某个或某些字段进行分组,并对每个组进行聚合运算。在本文中,我们将通过几个例子探讨如何使用SqlSugar进行分组查询。
Product
类代表商品信息,假设每个商品都有一个唯一的ID、名称、类别ID和价格。
C#[SugarTable("Product")]
public class Product
{
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public int Id { get; set; }
public string Name { get; set; }
public int CategoryId { get; set; }
public decimal Price { get; set; }
}
在这个类中,SugarTable
和SugarColumn
是SqlSugar提供的特性,用于映射实体类到数据库的表和列。IsPrimaryKey
标记该字段为主键,IsIdentity
表示该字段是自增的。
Sale
类代表销售记录,包括每次销售的唯一ID、销售的商品ID、销售数量、销售金额和销售年份。
C#[SugarTable("Sale")]
public class Sale
{
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public int Id { get; set; }
public int ProductId { get; set; }
public int Quantity { get; set; }
public decimal Amount { get; set; }
public int SaleYear { get; set; }
}
在Sale
实体类中,我们同样使用SugarTable
和SugarColumn
特性来定义与数据库表和列的映射。ProductId
字段表示这次销售中所售出商品的ID,它可以与Product
表中的Id
字段关联。
假设我们有一个Product
表,我们需要按照CategoryId
字段对商品进行分组,并计算每个类别下的商品数量。
C#// 创建一个针对Product实体的SqlSugar仓库实例
var productRepository = new SqlSugarRepository<Product>();
// 使用仓库实例的AsQueryable方法开始构建查询
var categoryCount = productRepository.AsQueryable()
// 根据CategoryId字段对Product表中的记录进行分组
.GroupBy(p => p.CategoryId)
// 选择每个分组的CategoryId和该CategoryId下的记录数
// SqlFunc.AggregateCount用于计算每个分组中CategoryId的数量
.Select(g => new { CategoryId = g.CategoryId, Count = SqlFunc.AggregateCount(g.CategoryId) })
// 将查询结果转换为列表
.ToList();
// 遍历查询结果列表
foreach (var item in categoryCount) {
// 打印每个类别的ID和该类别下的商品数量
Console.WriteLine($"{item.CategoryId}\t{item.Count}");
}
如果要根据多个字段进行分组,例如根据CategoryId
和SaleYear
分组,并计算每组的销售总额,可以这样做:
C#// 定义一个异步的主入口函数
static async Task Main()
{
// 创建一个针对Sale实体的SqlSugar仓库实例
var saleRepository = new SqlSugarRepository<Sale>();
// 使用仓库实例的AsQueryable方法开始构建查询
var saleSummary = saleRepository.AsQueryable()
// 根据ProductId和SaleYear字段对Sale表中的记录进行分组
.GroupBy(s => new { s.ProductId, s.SaleYear })
// 选择每个分组的ProductId, SaleYear和该分组下所有记录的Amount字段之和
// SqlFunc.AggregateSum用于计算每个分组中Amount的总和
.Select(g => new { g.ProductId, g.SaleYear, TotalSale = SqlFunc.AggregateSum(g.Amount) })
// 将查询结果转换为列表
.ToList();
// 遍历查询结果列表
foreach (var item in saleSummary)
{
// 打印每个产品每年的销售总额
Console.WriteLine($"{item.ProductId}\t{item.SaleYear}\t{item.TotalSale}");
}
}
分组聚合后,我们可能需要对结果进行筛选,比如找出销售总额超过一定值的分组。
C#// 定义一个异步的主入口函数
static async Task Main()
{
// 创建一个针对Sale实体的SqlSugar仓库实例
var saleRepository = new SqlSugarRepository<Sale>();
// 使用仓库实例的AsQueryable方法开始构建查询
var saleSummary = saleRepository.AsQueryable()
// 根据ProductId和SaleYear字段对Sale表中的记录进行分组
.GroupBy(s => new { s.ProductId, s.SaleYear })
// 选择每个分组的ProductId, SaleYear和该分组下所有记录的Amount字段之和
// SqlFunc.AggregateSum用于计算每个分组中Amount的总和,即总销售额
.Select(g => new { g.ProductId, g.SaleYear, TotalSale = SqlFunc.AggregateSum(g.Amount) })
// 将之前的查询结果作为一个新的表进行处理
.MergeTable()
// 从新表中筛选出总销售额超过10000的记录
.Where(x => x.TotalSale > 10000)
// 将查询结果转换为列表
.ToList();
// 遍历查询结果列表
foreach (var item in saleSummary)
{
// 打印每个满足条件的产品的ID、销售年份和总销售额
Console.WriteLine($"{item.ProductId}\t{item.SaleYear}\t{item.TotalSale}");
}
}
AsQueryable
方法开始构建对Sale
表的查询。GroupBy
方法按ProductId
和SaleYear
对记录进行分组。Select
方法选择每个分组的ProductId
、SaleYear
和TotalSale
(总销售额),其中使用SqlFunc.AggregateSum
来计算每个分组的销售总额。MergeTable
方法将之前的查询结果视为一个新的表,以便进行进一步的处理。Where
方法从新表中筛选出总销售额超过10000的记录。ToList
方法将查询结果转换为列表。对分组聚合的结果进行排序,例如按销售总额降序排列。
C#var saleRepository = new SqlSugarRepository<Sale>();
var saleSummary = saleRepository.AsQueryable()
.GroupBy(s => new { s.ProductId, s.SaleYear })
.Select(g => new { g.ProductId, g.SaleYear, TotalSale = SqlFunc.AggregateSum(g.Amount) })
.MergeTable()
.OrderByDescending(g=>g.TotalSale)
.ToList();
在进行连接查询后,我们也可以对结果进行分组。比如连接Product
表和Sale
表后,按商品类别分组计算销唀总额。
C#// 定义一个异步的主入口函数
static async Task Main()
{
// 创建一个针对Sale实体的SqlSugar仓库实例
var saleRepository = new SqlSugarRepository<Sale>();
// 使用仓库实例的AsQueryable方法开始构建查询
var saleSummary = saleRepository.AsQueryable()
// 使用LeftJoin方法连接Sale表和Product表,条件是两个表中的ProductId和Id字段相等
.LeftJoin<Product>((x, y) => x.ProductId == y.Id)
// 根据Product的Name和Sale的SaleYear字段对连接后的结果进行分组
.GroupBy((x, y) => new { y.Name, x.SaleYear })
// 选择每个分组的产品名称(Name),销售年份(SaleYear)和该分组下所有记录的Amount字段之和(TotalSale)
// SqlFunc.AggregateSum用于计算每个分组中Amount的总和,即总销售额
.Select((x, y) => new { y.Name, x.SaleYear, TotalSale = SqlFunc.AggregateSum(x.Amount) })
// 将之前的查询结果作为一个新的表进行处理
.MergeTable()
// 将查询结果转换为列表
.ToList();
// 遍历查询结果列表
foreach (var item in saleSummary)
{
// 打印每个满足条件的产品的名称、销售年份和总销售额
Console.WriteLine($"{item.Name}\t{item.SaleYear}\t{item.TotalSale}");
}
}
AsQueryable
方法开始构建对Sale
表的查询。LeftJoin
方法连接Sale
表和Product
表,连接条件是Sale
表中的ProductId
字段与Product
表中的Id
字段相等。GroupBy
方法按Product
的Name
和Sale
的SaleYear
对连接后的结果进行分组。Select
方法选择每个分组的产品名称(Name
)、销售年份(SaleYear
)和总销售额(TotalSale
),其中使用SqlFunc.AggregateSum
来计算每个分组的销售总额。MergeTable
方法将之前的查询结果视为一个新的表,以便进行进一步的处理。ToList
方法将查询结果转换为列表。通过上述例子,我们可以看到SqlSugar在处理分组查询时的灵活性和强大功能。无论是基本的分组聚合,还是分组后的筛选、排序,亦或是在连接查询结果上进行分组,SqlSugar都能提供简洁有效的解决方案。这使得开发者能够轻松应对复杂的业务需求,提高开发效率。
本文作者:技术老小子
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!