2009-08-09 101 views
3

我試圖選擇一個包含多個連接的表,一個用於使用COUNT的註釋數量,另一個用SUM選擇總的投票值,問題在於兩個連接互相影響,而不是顯示:mysql:多重連接問題

3票2條評論

我得到3 * 2 = 6票和2條* 3評論

這是我使用的查詢:

SELECT t.*, COUNT(c.id) as comments, COALESCE(SUM(v.vote), 0) as votes 
FROM (topics t) 
LEFT JOIN comments c ON c.topic_id = t.id 
LEFT JOIN votes v ON v.topic_id = t.id 
WHERE t.id = 9 

回答

3

你在做什麼是一個SQL反模式,我稱之爲戈德堡機器。爲什麼迫使它在單個SQL查詢中完成,使問題變得更加困難?

這是我如何會真正解決這個問題:

SELECT t.*, COUNT(c.id) as comments 
FROM topics t 
LEFT JOIN comments c ON c.topic_id = t.id 
WHERE t.id = 9; 

SELECT t.*, SUM(v.vote) as votes 
FROM topics t 
LEFT JOIN votes v ON v.topic_id = t.id 
WHERE t.id = 9; 

正如你已經發現,這兩個成一個查詢結果的笛卡爾乘積結合。在一個查詢中,可能會有聰明而微妙的方法來強制它給你正確的答案,但當你需要第三個統計時會發生什麼? 在兩個查詢中執行它更簡單。

+0

這不會爲數據庫帶來更多負載和更多工作嗎?或者數據庫難以使用多個連接來分離它們? – Dennis 2009-08-09 18:17:18

+0

大多數數據庫都有數據和索引頁面的內部緩存,所以它可能不成問題。此外,補償笛卡爾產品所需的工作可能會更糟糕。部分取決於您的特定系統和數據,因此最準確的答案需要在*您的*環境中進行測試。 – 2009-08-09 19:09:22

0
SELECT t.*, COUNT(DISTINCT c.id) as comments, COALESCE(SUM(v.vote), 0) as votes 
FROM (topics t) 
LEFT JOIN comments c ON c.topic_id = t.id 
LEFT JOIN votes v ON v.topic_id = t.id 
WHERE t.id = 9 
+0

我現在得到正確的評論數量,但我仍然得到了不正確的總票數,我試着向v.vote添加了DISTINCT,但那並不奏效。 – Dennis 2009-08-09 18:12:48

1
SELECT t.*, COUNT(c.id) as comments, COALESCE(SUM(v.vote), 0) as votes 
FROM (topics t) 
LEFT JOIN comments c ON c.topic_id = t.id 
LEFT JOIN votes v ON v.topic_id = t.id 
WHERE t.id = 9 
GROUP BY t.id 

或許

SELECT `topics`.*, 
(
    SELECT COUNT(*) 
    FROM `comments` 
    WHERE `topic_id` = `topics`.`id` 
) AS `num_comments`, 
(
    SELECT IFNULL(SUM(`vote`), 0) 
    FROM `votes` 
    WHERE `topic_id` = `topics`.`id` 
) AS `vote_total` 
FROM `topics` 
WHERE `id` = 9