2016-05-09 58 views
2

我正在爲連接三個表的報表頁編寫sql代碼。這是我寫的查詢。在表中使用COUNT函數加入

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滿足條件的每個School的Student.StartDate的計數。下面是我想用

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

我想上面的查詢被返回作爲我的主要查詢的一部分,但不知道如何實現查詢。任何幫助將不勝感激。謝謝

回答

4

當你想從不同的表彙總信息,您應該不加入表格然後進行彙總,但始終先建立彙總,然後加入這些彙總。在你的情況下,你可以通過計算不同的ID來避免問題,但這並不總是可能的(即當尋找總數或avarages時)。你可以有條件地計數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表達式。

+0

您的回答非常有用和信息豐富。我學到了一些新東西。非常感謝。我有一個小問題。當擺脫COALESCE表達式,這是否意味着我只有「SELECT CourseCount,StudentCount .....」。 – elfico

+0

@elfico:確實。從不同表格中選擇數據時,我使用表格限定符來顯示列的起始位置 - 即使列名稱應足夠描述:「SELECT c.CourseCount,s.StudentCount,s.StartCount ...」 –

0

你可以用條件聚合來做到這一點。只需添加這到SELECT

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

謝謝你的回答。我試了一下,它的工作,但總和不到1.我期待21,但得到20。@Kettner的答案,並得到正確的答案。學到了一些新思想。謝謝 – elfico

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 
+0

謝謝你的回答。我試了一下,它的工作,但總和不到1.我期待21,但得到20。@Kettner的答案,並得到正確的答案。學到了一些新思想。謝謝。 – elfico

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"; 
+0

它沒有工作。我使用@kettner的答案,它的工作。感謝您的幫助。 – elfico