VB.Net中计算DataTable指定金额总和(排除每个房间最后一天数据)
解决方法:排除每个房间最后一天数据后计算Amount总和
我来帮你搞定这个需求!核心思路是先找出每个房间对应的最大天数,再过滤掉该房间中等于这个最大天数的记录,最后对剩余记录的Amount字段求和。下面给你几种常用的实现方式:
方式一:C# LINQ(适用于内存中的DataTable)
如果你的DataTable是在内存中处理,用LINQ实现会很清晰:
- 先获取每个房间的最大天数:
// 假设你的DataTable变量名为dt var maxDaysPerRoom = dt.AsEnumerable() .GroupBy(row => row.Field<string>("Room No.")) // 按房间号分组 .ToDictionary(g => g.Key, g => g.Max(row => row.Field<int>("Day"))); // 每组取最大Day值
- 筛选非最后一天的记录并求和:
// 注意:Amount是带千分位的字符串,需要先转成数值类型再计算 decimal totalAmount = dt.AsEnumerable() .Where(row => row.Field<int>("Day") < maxDaysPerRoom[row.Field<string>("Room No.")] ) // 过滤掉每个房间的最后一天记录 .Sum(row => decimal.Parse(row.Field<string>("Amount").Replace(",", "")) ); // 转换Amount为decimal后求和
方式二:SQL查询(适用于数据来自数据库的场景)
如果数据存储在数据库里,直接用SQL查询会更高效:
子查询写法
SELECT SUM(CAST(REPLACE(Amount, ',', '') AS DECIMAL(18,2))) AS TotalAmount FROM YourTableName WHERE Day < ( SELECT MAX(Day) FROM YourTableName t WHERE t.[Room No.] = YourTableName.[Room No.] )
窗口函数写法(更简洁)
SELECT SUM(CAST(REPLACE(Amount, ',', '') AS DECIMAL(18,2))) AS TotalAmount FROM ( SELECT *, MAX(Day) OVER (PARTITION BY [Room No.]) AS MaxDayPerRoom FROM YourTableName ) t WHERE Day < MaxDayPerRoom
补充小提示
- 如果你的DataTable中
Amount字段已经是数值类型(比如decimal),可以去掉Replace和Parse步骤,直接用row.Field<decimal>("Amount")求和。 - 测试时可以先单独筛选出每个房间的最后一天记录,确认排除逻辑正确后,再验证总和是否符合预期。
内容的提问来源于stack exchange,提问作者Lady A
相关产品推荐
相关产品推荐

