2017-06-22 132 views
1

我有一個簡單的多學校管理系統,我正在努力獲得教師總數以及特定學校的學生總數。我的表結構如下:MYSQL加入三張表

 teachers 
-------------------------- 
id | schoolid | Name | etc... 
-------------------------- 
1 | 1  | Bob | 
2 | 1  | Sarah| 
3 | 2  | John | 


     students 
-------------------------- 
id | schoolid | Name | etc... 
-------------------------- 
1 | 1  | Jack | 
2 | 1  | David| 
3 | 2  | Adam | 

     schools 
-------------------------- 
id |  Name  | etc... 
--------------------------- 
1 | River Park High | 
2 | Stirling High | 

我可以指望剛剛全部用下面的查詢教師:

SELECT COUNT(a.id) AS `totalteachers` 
FROM teachers a 
LEFT JOIN schools b ON a.schoolid = b.id WHERE b.id = '1' 

,同樣我可以用下面的查詢次數,教師數量:

SELECT COUNT(a.id) AS `totalstudents` 
FROM students a 
LEFT JOIN schools b ON a.schoolid = b.id WHERE b.id = '1' 

但是,我試圖結合這兩個查詢來得到這樣一個簡單的結果:

totalstudents | totalteachers 
-------------------------------- 
     2  |  2 

我曾嘗試以下:

SELECT COUNT(a.id) as `totalteachers`, COUNT(c.id) as `totalstudents` 
FROM teachers a 
LEFT JOIN schools b ON a.schoolid = b.id 
LEFT JOIN students c ON c.schoolid=b.id WHERE b.id = '5' 

回答

2

多個左連接的問題是它爲每個學生生成每個老師的附加記錄;人爲地誇大你的計數

有四種方式來解決這個問題:(IMO最好什麼是安德魯骨所做的那樣)

只需選擇直列沒有連接,因此該計數不膨脹。 (最希望在我的腦海裏,因爲它很容易維護)

SELECT (SELECT COUNT(a.id) AS `totalteachers` 
     FROM teachers a 
     WHERE A.SchoolID = '1') as TotalTeachers 
    , (SELECT COUNT(a.id) AS `totalstudents` 
     FROM students a 
     WHERE a.SchoolID = '1') as TotalStudents 

使用子查詢,首先得到計數加入之前,然後再加入。由於count總是1,因此交叉連接可以工作。

SELECT totalTeachers, totalStudents 
FROM (SELECT COUNT(a.id) AS `totalteachers` 
     FROM teachers a 
     LEFT JOIN schools b 
     ON a.schoolid = b.id 
     WHERE b.id = '1') 
CROSS JOIN (SELECT COUNT(a.id) AS `totalstudents` 
      FROM students a 
      LEFT JOIN schools b ON a.schoolid = b.id 
      WHERE b.id = '1') 

使用關鍵字的計數範圍內不同以免重複計數和否定人工通貨膨脹(至少希望在我的腦海,因爲這隱藏了人工計數增加)

SELECT COUNT(distinct a.id) as `totalteachers`, COUNT(distinct c.id) as `totalstudents` 
FROM teachers a 
LEFT JOIN schools b ON a.schoolid = b.id 
LEFT JOIN students c ON c.schoolid=b.id WHERE b.id = '5' 

另一種方式要使用窗口函數,但是這些在mySQL中不可用。

+0

這是我正面臨的確切問題,人爲誇大計數!我選擇了你的第三個解決方案(使用不同的),它的功能就像一個魅力!感謝您抽出寶貴時間回答我的問題,並幫助我理解:)我很感激。 – Bruno

0
SELECT COUNT(t.id) AS TotalTeachers, COUNT(st.id) AS TotalStudents 
FROM schools s 
INNER JOIN teachers t 
ON s.id = t.schoolid 
INNER JOIN students st 
ON s.id = st.schoolid 

試試這個SQL。我沒有嘗試,但它應該工作。

3

你可以做這樣的事情

SELECT 
    id, name, s.total AS totalstudents, t.total AS totalteachers 
FROM schools 
    JOIN (SELECT schoolid, COUNT(id) AS total FROM teachers GROUP BY schoolid) 
    AS t ON t.schoolid = id   
    JOIN (SELECT schoolid, COUNT(id) AS total FROM students GROUP BY schoolid) 
    AS s ON s.schoolid = id 

那麼你可以添加where id = 2或任何限制的學校。

+0

感謝您的回答安德魯,我欣賞它:) – Bruno

+0

很好的答案。這使得學生可以輕鬆地設置where子句。 – xQbert