2013-05-29 33 views
0

在一個小型聊天服務中,兩個用戶有一個共同的聊天。 此SQL選擇您與之聊天的用戶列表。選擇不同並統計其他表格

SELECT DISTINCT user.user_id, user.username 
FROM user 
INNER JOIN message 
ON user.user_id = message.owner_user_id OR user.user_id = message.to_user_id 
WHERE message.owner_user_id = :activeUserId 
OR message.to_user_id = :activeUserId 
ORDER BY message.date_time DESC 

我還需要獲取兩個用戶之間發送的消息的數量。輸出是一個「文件夾」列表,活動用戶與每個用戶進行聊天。每個文件夾都包含用戶的用戶名和聊天消息的數量(活動用戶的消息數量與特定用戶的總數,以及特定用戶的消息數量)。

row1: (active user and JohnSmith have 33 messsages in their common chat.) 
    user_id = 1; 
    username = 'JohnSmith'; 
    message_count = 33; 

row2: (active user and Johnny have 43 messsages in their common chat.) 
    user_id = 2; 
    username = 'Johnny'; 
    message_count = 43; 

這怎麼能在一個SQL語句中完成?

回答

0

嘗試:

SELECT DISTINCT(user.user_id), user.username, COUNT(c.to_user_id) AS message_count 
FROM user 
INNER JOIN message 
    ON user.user_id = message.owner_user_id 
     OR user.user_id = message.to_user_id 
INNER JOIN message m1 
    ON user.user_id = m1.owner_user_id 
     OR user.user_id = m1.to_user_id 
WHERE message.owner_user_id = :activeUserId 
    OR message.to_user_id = :activeUserId 
ORDER BY message.date_time DESC 
+0

我得到這個:錯誤。 SQLSTATE [21000]:基數違規:1241操作數應該包含1列 – user1121487

+0

我已經更新了答案,但是,我認爲@EdGibbs的答案會更有益 –

0

眼下你 「扁平化」 的結果使用DISTINCT。您可以使用COUNT(*)功能和GROUP BY扁平計數:

SELECT DISTINCT user.user_id, user.username, COUNT(*) 
FROM user 
INNER JOIN message 
    ON user.user_id = message.owner_user_id OR user.user_id = message.to_user_id 
WHERE message.owner_user_id = :activeUserId OR message.to_user_id = :activeUserId 
GROUP BY user.user_id, user.username 
ORDER BY message.date_time DESC 

到您的查詢的唯一的變化是額外的列(COUNT(*))和GROUP BY線。

+0

這樣第一個用戶得到33個計數,第二個用戶獲得66個計數。 – user1121487

+0

嗯;那麼有一些重複計算正在進行。我必須知道你的表是怎樣調試的。你有沒有嘗試Gordon Linoff的答案?它看起來像是在考慮雙重計數。 –

+0

我已更新我的帖子來澄清一些。 – user1121487

0

你的問題似乎有點模棱兩可。您似乎想要統計從一個用戶到他們通信的每個其他用戶的消息 - 無論他們是消息的「從」還是「到」角色。

在處理消息時,一種方法是使用較小的用戶標識,然後是較大的用戶標識對它們進行標準化。這樣的查詢的結果對於您的用戶將是一行,如下所示:

1 'JohnSmith' 2 'Johnny' 33 

而不是兩個單獨的行。你也可以得到兩個單獨的行,但這對我來說似乎不太有用。

產生輸出的這種風格的查詢是:

select least(m.owner_user_id, m.to_user_id) as uid1, 
     greatest(m.owner_user_id, m.to_user_id) as uid2, 
     u1.username, u2.username, count(*) as nummessages 
from message m join 
    user u1 
    on u1.user_id = least(m.owner_user_id, m.to_user_id) join 
    user u2 
    on u2.user_id = greatest(m.owner_user_id, m.to_user_id) 
WHERE m.owner_user_id = :activeUserId or 
     m.to_user_id = :activeUserId 
group by least(m.owner_user_id, m.to_user_id) as uid1, 
     greatest(m.owner_user_id, m.to_user_id); 
+0

我已更新我的帖子來澄清一些。 – user1121487