2013-02-19 41 views
1

我們使用trac的定製版本,其中人們可以根據兩個條件給出錯誤分數,我們稱它們爲severityimportance如何修復trac報告中的雙LEFT JOIN

爲了簡單起見,讓我們說,該數據庫包含以下表格:

ticket

id | title   | reporter 
1 | SQL injection | Torvalds 
2 | Buffer Overflow | Linus 
3 | Localization | bofh 

votes

ticket_id | value | type  | voter 
1   | 4  | severity | Linus 
1   | 2  | severity | Torvalds 
1   | 3  | severity | bofh 
1   | 4  | importance | Linus 
1   | 3  | importance | Torvalds 
2   | 4  | severity | Linus 
2   | 2  | severity | Torvalds 
2   | 1  | importance | Linus 
2   | 1  | importance | bofh 
3   | 1  | importance | Linus 

因此,例如,第一行是指用戶Linus建議4作爲票#1的嚴重性分數。

現在我有,我用它來獲得平均分數TRAC報告下面的SQL查詢:

SELECT t.title, t.reporter, AVG(vs.value), AVG(vi.value), COUNT(vs.value), COUNT(vi.value) 
FROM ticket t 
LEFT JOIN votes vs ON vs.type = 'severity' AND vs.ticket_id=t.id 
LEFT JOIN votes vi ON vi.type = 'importance' AND vi.ticket_id=t.id; 

在我的希望,這應該返回一個表具有以下值:

title | reporter | severity avg | importance avg | number of sev. votes | number of imp. votes 
SQL injection | Torvalds | 3 | 3.5 | 3 | 2 

因此告訴我有多少人投票支票,他們的選票是什麼。

但是,由於LEFT JOIN的工作方式,我得到的條目是嚴重性和重要性投票的笛卡爾乘積,所以平均值仍然有效,而兩個計數都設置爲3x2 = 6而不是正確的值。

有沒有簡單的方法來解決這個查詢,以便它返回我想要的?

回答

2

結合CASE語句與聚合函數:

SELECT 
    t.title, 
    t.reporter, 
    SUM(CASE WHEN v.type = 'importance' THEN 1 ELSE 0 END) AS Count_Imp, 
    SUM(CASE WHEN v.type = 'severity' THEN 1 ELSE 0 END) AS Count_Sev, 
    SUM(CASE WHEN v.type = 'importance' THEN v.value ELSE 0 END)/
    Count_Imp AS Avg_Imp, 
    SUM(CASE WHEN v.type = 'severity' THEN 1 ELSE 0 END)/
    Count_Sev AS Avg_Sev 
FROM 
    ticket t 
    LEFT JOIN votes v 
    ON v.ticket_id = t.id; 

如果Trac的SQL不允許你重新使用別名Count_ImpCount_Sev你會簡單地重複這些語句在平均計算列。

+0

謝謝!最後,我用類似的方式解決了這個問題,用一個子選擇而不是一個LEFT JOIN – 2013-02-22 13:21:03

+0

非常歡迎。 – bernie 2013-02-22 14:38:44