我正在尝试在C#应用程序中执行此SQL SELECT:
SELECT SUM( a.VALUE_A) / SUM( a.VALUE_B)
FROM "TABLE" a
WHERE DATE_COLUMN = to_date('12/05/2018', 'DD/MM/YYYY');
将此C#与LINQ代码一起使用:
dto.day = await database.Where(x => x.DATE_COLUMN.Date == date_filtered)
.SumAsync(x => (x.VALUE_A) / (x.VALUE_B));
但是抛出一个异常,称除数为零。因此,我尝试通过在SumAsync()方法中添加三元IF来处理它:
dto.day = await database.Where(x => x.DATE_COLUMN.Date == date_filtered)
.SumAsync(x => x.VALUE_B == 0 ? 0 : (x.VALUE_A) / (x.VALUE_B));
但是最终结果与直接SQL结果不同:
SQL给出正确的结果,例如:86.25
C#给出了错误的结果:227.87
拜托,我在做什么错了?
答案 0 :(得分:4)
操作顺序是关键。请尝试以下操作:
var values = database.Where(x => x.DATE_COLUMN.Date == date_filtered)
.Select(x => new {x.VALUE_A, x.VALUE_B}).ToList();
dto.day = values.Sum(s => s.VALUE_A) / values.Sum(s => s.VALUE_B);
编辑:
为清楚起见,这是细分。在查询中,您将VALUE_A的总和除以VALUE_B的总和。
在LINQ语句中,您要对每条记录的VALUE_A / VALUE_B的结果求和。
在我的回答中,我正在创建一个匿名对象,该对象仅获得VALUE_A和VALUE_B。然后,我将两者的总和相除。希望这是一个更好的解释。
答案 1 :(得分:1)
您得到错误的结果,因为Sum(a) / Sum(b)
与Sum(a / b)
不同。你想要的是
(a1 + a2 + ... aN) / (b1 + b2 + ...bN)
获得的是
(a1 / b1 + a2 / b2 + ... aN / bN)
因此,要获得所需的结果,在LINQ中,通常需要对Sum
或类似集合的结果进行2个GroupBy
调用。由于查询是顶级查询,因此您可以执行2个数据库Sum
查询并从中查询结果,也可以使用伪造的按常量分组技巧通过一个数据库查询来获取。像这样:
var query = db.Table
.Where(e => e.DATE_COLUMN.Date == date_filtered)
.GroupBy(e => 1) // <--
.Select(g => new
{
SumA = g.Sum(e => e.VALUE_A), // <--
SumB = g.Sum(e => e.VALUE_B), // <--
})
.Select(e => e.SumB == 0 ? 0 : e.SumA / e.SumB);
var result = await query.FirstOrDefaultAsync();