我正在编写一个连接三个表的报表页面的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());
我希望上面的查询作为主查询的一部分返回,但不知道如何实现它。任何帮助将不胜感激。感谢
答案 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";