2013-12-22 88 views
2

我無法圍繞這個包裹我的頭。我有一個客戶 - 員工溝通系統。在管理員端,我試圖檢索用戶列表,其中包含該用戶的總消息數,全部新消息,最後消息日期和最後消息。SQL SELECT頂行和聚合計數

邏輯的位:0

  • 發送者或接收者的值,意味着工作人員發送或接收它。
  • X的發送者或接收者值,表示接收或發送它的ID值爲X的用戶。

樣本數據:

ID |date     |new |sender |receiver |message 
----+-----------------------+-------+-------+-----------+------------ 
1 |2013-12-22 08:19:12 |1  |2  |0   |Hello 
2 |2013-12-22 08:23:19 |0  |0  |2   |Hello There 
3 |2013-12-22 08:23:19 |0  |0  |4   |Hello There 
4 |2013-12-22 10:09:44 |1  |2  |0   |The latest message 

所需的輸出:

user ID |total_messages |total_new |latest_date   |latest_messsage 
------------------------------------------------------------------------------ 
2  |3    |2   |2013-12-22 10:09:44 |The latest message 
4  |1    |0   |2013-12-22 08:23:19 |Hello There 

我使用SQL Server 2008

+2

儘量避免使用幻數,比如'0'了特殊的含義。如果沒有用戶發送消息,則該值應該爲NULL,而不是用戶指示缺少。這也使得篩選和加入更容易,並且不會破壞聲明性參照完整性。 –

回答

1

拆分選擇第一行,並在集合行的邏輯兩個查詢和UNION結果。

SELECT TOP 1 --columns-- 
FROM yourTable 

UNION ALL 

SELECT --columns-- 
FROM yourTable 
GROUP BY --columns-- 

(沒有關於表結構或什麼是所需的輸出更多的細節,這是最好的答案我可以想出)

+0

這不會指定X用戶具有X結果,因爲最新消息和最新日期必須屬於該用戶,所以我更多地考慮JOIN。 – user1695981

+0

你可以編輯問題並添加所需的輸出嗎? –

+0

我做到了。也許我對這個過程一無所知,但是在stackoverflow上設計空間需要一些工作。 – user1695981

1

我不知道什麼是你的數據庫表。但我可以說你有一個消息表和一個用戶表。

SELECT 
    [userId], 
    (SELECT 
     count(*) 
    FROM messages 
    WHERE u.userId = messages.UserId) AS totalMessages, 
    (SELECT 
     TOP 1 [TimeStamp] 
    FROM messages 
    WHERE messages.UserId = u.UserId 
    ORDER BY messages.MessageId DESC), 
    (SELECT 
     TOP 1 [Message] 
    FROM messages 
    WHERE messages.UserId = u.UserId 
    ORDER BY messages.MessageId DESC) 
FROM users u 

您可以像這樣計算髮件人和收件人列。

1

由於用戶發送或接收您的總計似乎並不重要,有一種方法是通過用戶(發送者或接收者)將消息數據列在單個列中(我使用CTE) ,然後使用該配置匯聚並JOIN本身得到latest_message

WITH Users_CTE AS 
(
    SELECT sender AS user_id, ID, new, date, message 
    FROM Messages 
    WHERE sender <> 0 
    UNION 
    SELECT receiver AS user_id, ID, new, date, message 
    FROM Messages 
    WHERE receiver <> 0 
) 

SELECT m.user_id, m.total_messages, m.total_new, m.latest_date, u.message AS latest_message 
FROM (SELECT user_id 
     , COUNT(*) AS total_messages 
     , SUM(new) AS total_new 
     , MAX(date) AS latest_date 
     FROM Users_CTE 
     GROUP BY user_id) AS m 
    INNER JOIN Users_CTE AS u ON u.user_id = m.user_id 
    AND u.date = m.latest_date 

sqlfiddle