LINQ取查询中多个字段的平均值

时间:2014-05-13 17:43:19

标签: c# sql linq

我有类似以下的查询

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,我不想将它们包含在平均值计算中。我想如果有一个空值我可以减少计数。有更好的方法吗?

4 个答案:

答案 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,将流程与数据采集分开。