2016-02-13 100 views
-1

4 tables Relationship如何避免重複的MySQL子查詢中的列?

enter image description here

我是從上述4表使用以下查詢

SELECT 
(SELECT SUM(CASE when c.Training_Id=1 then 1 else 0 end) 
FROM courses c 
INNER JOIN enrolled_students es 
ON c.Course_Id = es.Course_Id 
) STEM, 

(SELECT SUM(CASE when c.Training_Id=2 then 1 else 0 end) 
FROM courses c 
INNER JOIN enrolled_students es ON c.Course_Id = es.Course_Id 
) MA, 
c.* FROM campus c; 

檢索結果與該查詢的問題是,兩(2)學生在STEM和一(1 )學生在校園_Id 3的MA,但它對所有校園的重複記錄。我想要如果校園沒有學生,那麼應該有'0'零。

+1

正確的創建和插入語句,以及相應的預期結果謝謝。最好也是SQLfiddle。 – Strawberry

回答

1

您需要篩選Campus_Id。但首先你必須使用不同的表別名。將您的最後一行更改爲ca.* FROM campus ca。然後,可以在子查詢中使用where子句(WHERE c.Campus_Id = ca.Campus_Id)。

SELECT 
(SELECT SUM(CASE when c.Training_Id=1 then 1 else 0 end) 
FROM courses c 
INNER JOIN enrolled_students es 
ON c.Course_Id = es.Course_Id 
WHERE c.Campus_Id = ca.Campus_Id -- line added 
) STEM, 

(SELECT SUM(CASE when c.Training_Id=2 then 1 else 0 end) 
FROM courses c 
INNER JOIN enrolled_students es ON c.Course_Id = es.Course_Id 
WHERE c.Campus_Id = ca.Campus_Id -- line added 
) MA, 
ca.* FROM campus ca; -- line changed 

這應該可以解決您的問題。

爲了提高性能,您還可以通過Training_Id來篩選子查詢。在第一個子選擇中,您只需要使用Training_Id=1的行。所以,你可以改變你的where子句:

WHERE c.Campus_Id = ca.Campus_Id 
    AND c.Training_Id = 1 

這樣做,你也可以使用COUNT代替SUM。所以,你再選擇看起來像:

SELECT COUNT(1) 
FROM courses c 
INNER JOIN enrolled_students es ON c.Course_Id = es.Course_Id 
WHERE c.Campus_Id = ca.Campus_Id AND c.Training_Id = 1 

爲了避免重複代碼(你的子查詢幾乎是相等的),你可以通過Campus_Id加入所有需要的表和組:

select 
    COUNT(co.Training_Id=1 OR NULL) STEM, 
    COUNT(co.Training_Id=2 OR NULL) MA, 
    ca.Campus_Id 
from campus ca 
left join courses co on co.Campus_Id = ca.Campus_Id 
left join enrolled_students es on es.Course_Id = co.Course_Id 
where co.Training_Id in (1, 2) 
group by ca.Campus_Id