我有类似以下的查询
select q1, q2, q3, q4, average from results
我需要计算每行平均列中q1到q5的平均值。我有以下
var query = from T in db.results
select new ResultsCustom
{
q1, q2, q3, q4
average = ((double)(T.q1 ?? 0.0)
+ (double)(T.q2 ?? 0.0)
+ (double)(T.q3 ?? 0.0)
+ (double)(T.q4 ?? 0.0)
) / 4};
问题是q1到q4可以为null,这会使平均值偏离。如果它们为null,我不想将它们包含在平均值计算中。我想如果有一个空值我可以减少计数。有更好的方法吗?
答案 0 :(得分:4)
这不可能转换为SQL,但你可以这样做:
var query = from T in db.results
select new ResultsCustom
{
q1, q2, q3, q4
average = (new double?[] { T.q1, T.q2, T.q3, T.q4 }).Average()
};
因为Average()
将忽略空值。
要获得结果并在Linq-to-Objects中执行平均值,请执行以下操作:
var query = (from T in db.results select new {q1, q2, q3, q4}).AsEnumerable()
.Select(r => new ResultsCustom
{
r.q1, r.q2, r.q3, r.q4,
average = (new double?[] { r.q1, r.q2, r.q3, r.q4 }).Average()
}
);
答案 1 :(得分:1)
你没有计算那里的平均值。只需使用标准公式sum / count
。
...
let sum = q1.GetValueOrDefault() + q2.GetValueOrDefault() + ...
let count = (q1 != null ? 1 : 0) + ...
let avg = sum / count
...
您可能还需要定义count == 0
时应该发生的事情。
答案 2 :(得分:0)
double GetAverage(T)
{
List<double> list = new List<double>();
if (T.q1 != null) list.Add(T.q1);
if (T.q2 != null) list.Add(T.q2);
if (T.q3 != null) list.Add(T.q3);
if (T.q4 != null) list.Add(T.q4);
return list.Average();
}
答案 3 :(得分:0)
您可以如下概括(未经测试):
double GetAverage(List<double> doublesList)
{
var list = doublesList.Where(x => x != null).ToList();
return list.Average();
}
返回任意长度的doubles
列表的平均值,忽略nulls
,将流程与数据采集分开。