如何使用LINQ按GoodsCode分组并获取ChangeDate最大值?
筛选分组后每组最新ChangeDate的完整记录
需求说明
从GOODS_TABLE中筛选出按GoodsCode分组后,每组内ChangeDate最大的完整记录。
示例数据
TABLE - GOODS_TABLE GOODS_CODE GOODS_PRICE CHANGE_DATE GOODS_PART 8800 1000 20220911 1 8800 1200 20220914 1 8801 1300 20220928 2 8801 1500 20220929 2 8802 1300 20220916 3 8802 1500 20221001 3 8802 2400 20221004 3
期望输出
GOODS_CODE GOODS_PRICE CHANGE_DATE GOODS_PART 8800 1200 20220914 1 8801 1500 20220929 2 8802 2400 20221004 3
当前尝试的LINQ写法
from p in goods group p by { p.goods_code, p.goods_price, p.change_date, p.goods_part } into g select (goods_code: g.Key.goods_code, goods_price: g.Key.goods_price, goods_part : g.Key.goods_part, change_date: g.Max(p => p.change_date));
疑问
是否必须将所有需要的列都纳入分组键?有没有其他更合适的LINQ实现方式?
解答
1. 关于分组键的疑问
完全不需要把所有列都放进分组键。你当前的写法逻辑有误——把所有列都作为分组键,等于每条记录单独成组,最后取的Max(change_date)其实就是原记录的日期,根本没实现按GoodsCode分组取最新记录的需求。
2. 正确的LINQ实现方式
方式一:分组后排序取第一条
先按GoodsCode分组,每组内按ChangeDate降序排序,再取每组的第一条记录,逻辑直观易懂:
var result = goods .GroupBy(p => p.goods_code) .Select(g => g.OrderByDescending(p => p.change_date).First());
方式二:使用MaxBy(.NET 6+)
如果项目基于.NET 6或更高版本,直接用MaxBy方法更简洁高效,它会直接返回每组中change_date最大的完整记录:
var result = goods .GroupBy(p => p.goods_code) .Select(g => g.MaxBy(p => p.change_date));
方式三:子查询匹配最大日期
若处理大数据集,可先找出每组的最大日期,再关联原数据获取完整记录,避免排序带来的性能开销:
// 先获取每组的最大ChangeDate var maxDateGroups = goods .GroupBy(p => p.goods_code) .Select(g => new { GoodsCode = g.Key, MaxChangeDate = g.Max(p => p.change_date) }); // 关联原表获取完整记录 var result = from item in goods join md in maxDateGroups on new { item.goods_code, item.change_date } equals new { md.GoodsCode, md.MaxChangeDate } select item;
内容的提问来源于stack exchange,提问作者Polaris Nation
相关产品推荐
相关产品推荐

