两个不同的聚合查询组合在一起:可能吗? (EF 核心 5,SQL 服务器)

Two distinct aggregate queries combined: possible? (EF Core 5, SQL Server)

我有一个 table 这样的:

id (PK) name course date grade
1 Jane french 2016-11-20 20
3 CARL french 2015-09-02 30
4 Anna french 2016-11-20 25
5 JON french 2016-09-02 56
6 Linda english 2016-09-02 22
7 TIM english 2016-11-20 23
8 JON english 2016-11-20 44

我想知道是否可以用一个查询来回答以下两个问题:

是否可以用一个查询来回答这两个问题?或者,是不是因为我要“按”不同的列“分组”,所以我无法在单个查询中实现这一点?

我使用的是 EF Core 5.0,由 SQL 服务器数据库支持,所以如果我可以使用 LINQ groupby 运算符实现这一点,那就太好了,但如果不能,我不介意写直接 SQL 如果它更有效率。

将它们结合起来会有些困难,而且在 EF/Linq 中几乎不可能做到。我会说只有在查询 table 两次非常低效时才值得。否则,只需在 EF 中或作为一个 T-SQL 批次的两个查询来执行它们。

  • 第一个查询可以在 T-SQL
  • 中轻松回答
SELECT
  c.Course,
  AVG(c.Grade * 1.0) AvgGrade
FROM Course c
GROUP BY
  c.Course;

在 Linq 中

from c in Course
group by c.Course into g
select new {
    Course: g.Key,
    AvgGrade: g.Avg(c2 => c2.Grade * 1.0)
}

  • 同样,另一个查询
SELECT
  c.Course,
  AVG(Count * 1.0) AvgCount
FROM (
    SELECT
      c.Course,
      COUNT(*) Count
    FROM Course c
    GROUP BY
      c.Course,
      c.Date
) c
GROUP BY
  c.Course;

在 Linq 中

from c in Course
group by new {c.Course, c.Date} into g
select new {
    Course: g.Key.Course,
    Count: g.Count()
} into c2
group by c2.Course into g2
select new {
    Course: g2.Key,
    AvgCount: g2.Average(c3 => c3.Count * 1.0)
}

要结合使用,您可以使用以下内容:

由于已经存在聚合,并且您不能(在数学上)对平均值进行平均,因此这变得更加复杂。所以你需要使用SUM / COUNT并嵌套分组。

SELECT
  c.Course,
  AVG(Count * 1.0) AvgCount,
  SUM(c.TotalGrades) * 1.0 / SUM(Count) AvgGrade
FROM (
    SELECT
      c.Course,
      COUNT(*) Count,
      SUM(c.Grade) TotalGrades
    FROM Course c
    GROUP BY
      c.Course,
      c.Date
) c
GROUP BY
  c.Course;

在 Linq 中

from c in Course
group by new {c.Course, c.Date} into g
select new {
    Course: g.Key.Course,
    Count: g.Count(),
    TotalGrades: g.Sum(c3 => c3.Grade)
} into c2
group by c2.Course into g2
select new {
    Course: g2.Key,
    AvgCount: g2.Average(c3 => c3.Count * 1.0).
    AvgGrade: g2.Sum(c3 => c3.TotalGrades) * 1.0 / g2.Sum(c3 => c3.Count)
}

db<>fiddle