在表联接中使用COUNT函数

时间:2016-05-09 10:27:40

标签: sql asp.net sql-server

我正在编写一个连接三个表的报表页面的sql代码。这是我写的查询。

comm.CommandText = "SELECT Count(DISTINCT Courses.CourseID) AS CourseCount, Count(DISTINCT Students.StudentID) AS StudentCount, Count(Students.StartDate) AS StartCount, School.Name, School.StartDate, School.SchoolFees " +
                "FROM Schools " +
                "LEFT JOIN Courses ON (School.SchoolID = Courses.SchoolId) " +
                "LEFT JOIN Students ON (School.SchoolID = Student.SchoolID) " +
                "WHERE School.Active = 1 " +
                "GROUP BY School.Name, School.StartDate, School.SchoolFees";

以上查询效果很好。但我想显示Student.StartDate满足条件的每所学校的Student.StartDate计数。这是我想要使用的查询

SELECT Count(Students.StartDate)
FROM Students
WHERE Student.StartDate >= DATEADD(month, -1, GETDATE());

我希望上面的查询作为主查询的一部分返回,但不知道如何实现它。任何帮助将不胜感激。感谢

4 个答案:

答案 0 :(得分:4)

当您需要来自不同表的聚合时,不应该加入表然后聚合,而是始终首先构建聚合并加入这些聚合。在您的情况下,您可以通过计算不同的ID来避免问题,但这并不总是可行的(即,在查找总和或平均值时)。您可以使用CASE WHEN有条件地计算。

SELECT 
  COALESCE(c.CourseCount, 0) AS CourseCount,
  COALESCE(s.StudentCount, 0) AS StudentCount,
  COALESCE(s.StartCount, 0) AS StartCount,
  School.Name, 
  School.StartDate, 
  School.SchoolFees
FROM Schools
LEFT JOIN
(
  SELECT SchoolID, COUNT(*) AS CourseCount
  FROM Courses 
  GROUP BY SchoolID
) c ON c.SchoolId = School.SchoolID
LEFT JOIN
(
  SELECT 
    SchoolID, 
    COUNT(*) AS StudentCount,
    COUNT(CASE WHEN StartDate >= DATEADD(month, -1, GETDATE() THEN 1 END) as StartCount
  FROM Students 
  GROUP BY SchoolID
) s ON s.SchoolId = School.SchoolID
WHERE School.Active = 1;

如果保证每所学校至少有一名学生和一门课程(可能就是这种情况),您可以将外部联接更改为内部联接,从而摆脱COALESCE表达式。

答案 1 :(得分:0)

您可以使用条件聚合执行此操作。只需将其添加到SELECT

即可
SUM(CASE WHEN Student.StartDate >= DATEADD(month,-1, GETDATE()) THEN 1 ELSE 0 END) as RecentStudents

答案 2 :(得分:0)

使用CASE WHEN,您可以解决此问题,

SELECT  Count(DISTINCT Courses.CourseID)    AS  CourseCount, 
        Count(DISTINCT Students.StudentID)  AS  StudentCount, 
        Count(Students.StartDate) AS StartCount, 
        Sum(CASE WHEN Student.StartDate >= DATEADD(month,-1, GETDATE()) 
                THEN 1 ELSE 0 END)  AS  StartDateCount ,
        School.Name, School.StartDate, School.SchoolFees
FROM Schools
LEFT JOIN Courses ON (School.SchoolID = Courses.SchoolId)
LEFT JOIN Students ON (School.SchoolID = Student.SchoolID)
WHERE School.Active = 1
GROUP BY School.Name, School.StartDate, School.SchoolFees

答案 3 :(得分:0)

我想这有帮助

   myConnect.Open();
        comm.CommandText = "SELECT Count(DISTINCT Courses.CourseID) AS CourseCount, Count(DISTINCT Students.StudentID) AS StudentCount, Count(Students.StartDate) AS StartCount, School.Name, School.StartDate, School.SchoolFees, " +
        "(SELECT Count(stu.StartDate) FROM Students stu WHERE School.SchoolID = stu.SchoolID AND stu.StartDate >= DATEADD(month,-1, GETDATE())) AS CountStartDate" + // your count
        "FROM Schools " +
        "LEFT JOIN Courses ON (School.SchoolID = Courses.SchoolId) " +
        "LEFT JOIN Students ON (School.SchoolID = Student.SchoolID) " +
        "WHERE School.Active = 1 " +
        "GROUP BY School.Name, School.StartDate, School.SchoolFees";