2011-10-13 138 views
3

它必須是很容易的,但我不認爲任何解決方案中也可以找到答案的地方...左加入2和表1個表

我得到了表「用戶」
和一個表 '博客'(USER_ID,博文)
和一個表 '消息'(USER_ID,消息)

我想有以下結果:

User | count(blogs) | count(messages) 
Jim | 0 | 3 
Tom | 2 | 3 
Tim | 0 | 1 
Foo | 2 | 0 

因此,我所做的是:

SELECT u.id, count(b.id), count(m.id) FROM `users` u 
LEFT JOIN blogs b ON b.user_id = u.id 
LEFT JOIN messages m ON m.user_id = u.id 
GROUP BY u.id 

它顯然不起作用,因爲第二個左連接涉及博客而不是用戶。有什麼建議麼?

回答

3

首先,如果你只想要計數值,你可以做的子查詢:

select u.id, u.name, 
    (select count(b.id) from blogs where userid = u.id) as 'blogs', 
    (select count(m.id) from messages where userid = u.id) as 'messages' 
from 'users' 

請注意,這只是一個普通的SQL例子,我這​​裏沒有的MySQL數據庫,現在對它進行測試。

另一方面,您可以加入,但您應該使用outer join以包含沒有博客但帶有消息的用戶。這意味着你多次獲得多個用戶,所以一個小組將會有所幫助。

+0

+1子選擇是最好和最快的選擇。 – Johan

+0

好的,謝謝你們!我一直認爲子語是邪惡的。 – user993692

+0

@ user993692 - 取決於子查詢。現代數據庫足夠聰明,可以優化子查詢,在這種情況下,您只需要一個關鍵搜索,這非常輕便(假設您沒有數十萬用戶)。 – z00l

1

如果在select中使用聚合函數,SQL將把所有行合併到一行中。
爲了獲得超過1行,您必須使用group by子句。
然後,SQL將爲每個用戶生成總計。

最快的選項

SELECT 
    u.id 
    , (SELECT(COUNT(*) FROM blogs b WHERE b.user_id = u.id) as blogcount 
    , (SELECT(COUNT(*) FROM messages m WHERE m.user_id = u.id) as messagecount 
FROM users u 

爲什麼您的代碼不起作用

SELECT u.id, count(b.id), count(m.id) 
FROM users u 
LEFT JOIN blogs b ON b.user_id = u.id  <<-- 3 matches multiplies # of rows *3 
LEFT JOIN messages m ON m.user_id = u.id <<-- 5 matches multiplies # of rows *5 
GROUP BY u.id 

計數將被關閉,因爲你指望重複的項目。

簡單的修復,但會比選擇1
慢如果只算不同的ID,你會得到正確的計數:

SELECT u.id, count(DISTNICT b.id), count(DISTINCT m.id) 
FROM users u 
LEFT JOIN blogs b ON b.user_id = u.id  
LEFT JOIN messages m ON m.user_id = u.id  
GROUP BY u.id 
+0

我已經拿到了'group by',只是忘了寫下來。但結果仍然是錯誤的,看起來像: '用戶|計數(博客)|計數(消息) Jim | 0 | 0 Tom | 2 | 2 Tim | 0 | 0 Foo | 2 | 2' – user993692

+0

thx爲您解釋! – user993692