You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求对应SQL Server UNBOUNDED PRECEDING窗口函数的C# LINQ查询

问题:将SQL累计求和查询转换为C# LINQ查询

原始数据表

日期EarnedMHRSDayValMHRSPer
2022/3/8766076.618341360.005743504
2022/3/91418.135770.03134451
2022/3/1021405.1894330.105336539
2022/3/1132907.9397740.21798649
2022/3/1243705.6885730.277787749
2022/3/1352907.9397740.21798649
2022/3/1461405.1894330.105336539
2022/3/157418.135770.03134451
2022/3/16876.618341360.005743504
2022/3/1798.6453215180.000648075

目标SQL查询

SELECT [Date],
        SUM(EarnedMHRS) OVER(ORDER BY DayVal ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) As EarnedMHRS,
        Round(SUM(MHRS) OVER(ORDER BY DayVal ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW),0) AS MHRS, 
        per      
        FROM TblPanning;

尝试的LINQ代码(未成功)

decimal? runningTotal = 0;
decimal? runningTotalMHRS = 0;
var tmpOutput2 = tmpOutput1.Select(item =>
     {
         runningTotal += item.EarnedMHRS;
         runningTotalMHRS += item.MHRS;
         return new
         {
             item.Date,
             MHRS = item.DayVal == totalDays ? totallMhrs : Math.Round(runningTotalMHRS ?? 0, 0),
             item.per,
             EarnedMHRS = runningTotal,
         };
     });

期望输出结果

日期EarnedMHRSMHRSper
2022-03-08766.00770.00574350382867894
2022-03-09766.004950.0313445103804797
2022-03-10766.0019000.105336538836155
2022-03-11766.0048080.217986488988673
2022-03-12766.0085140.277787748142283
2022-03-13766.00114220.217986488988673
2022-03-14766.00128270.105336538836155
2022-03-15766.00132450.0313445103804797
2022-03-16766.00133210.00574350382867894
2022-03-17766.00133400.000648075073801102

解决方案

你的LINQ代码存在两个核心问题:一是未正确处理EarnedMHRS的null值,二是多余的条件判断干扰了累计逻辑。修正后的代码如下:

// 先按DayVal排序,对齐SQL中的ORDER BY逻辑
var sortedData = tmpOutput1.OrderBy(item => item.DayVal).ToList();

decimal runningTotalEarned = 0;
decimal runningTotalMHRS = 0;

var tmpOutput2 = sortedData.Select(item =>
{
    // 处理EarnedMHRS的null值,null时按0累加
    runningTotalEarned += item.EarnedMHRS ?? 0;
    // 累加MHRS
    runningTotalMHRS += item.MHRS;
    
    return new
    {
        item.Date,
        EarnedMHRS = runningTotalEarned,
        MHRS = Math.Round(runningTotalMHRS, 0),
        item.per
    };
});

关键说明

  1. 必须先排序:SQL窗口函数依赖ORDER BY DayVal确定累计顺序,LINQ中需要先对数据排序,否则累计结果会混乱。
  2. null值处理:原始数据中大部分EarnedMHRS为null,用item.EarnedMHRS ?? 0确保累计时不会出现异常,且结果始终为766。
  3. 移除多余条件:SQL中没有item.DayVal == totalDays的逻辑,直接对累计的runningTotalMHRS取整即可对齐目标结果。

内容的提问来源于stack exchange,提问作者avnish maddheshiya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 01:06:24