2012-04-03 94 views
2

我有一個包含用戶消息的表。我如何使用SQL來選擇用戶發送的所有消息。我想通過MessageSenderUserID對結果進行分組。我也想只返回最近的每個收件人。從另一個ID分組中選擇最近的(前1個)

我試圖在having子句中使用MAX,但似乎這不是正確的解決方案。

我可能最好將其描述爲以下查詢的組合:

SELECT TOP 1 MessageID, MessageSent, MessageSenderUserID, MessageRecipientUserID 
FROM [Messaging_Message] 
WHERE MessageSenderUserID = 799 
ORDER BY MessageSent DESC 

SELECT MessageSenderUserID 
FROM [Messaging_Message] 
GROUP BY MessageSenderUserID 

謝謝!

+1

你可以張貼一些示例數據和所需的O/P – Teja 2012-04-03 21:04:30

回答

5

我VE最近才知道這個(最令人驚訝的&樂趣)獲得一組前1項的方式:

select top 1 with ties 
    MessageID, 
    MessageSent, 
    MessageSenderUserID, 
    MessageRecipientUserID 
from [Messaging_Message] 
order by row_number() over (partition by MessageSenderUserID 
          order by MessageSent desc) 

訣竅是爲了通過 - 結果是通過參加分區分組和排序關鍵字排序,導致每個組接收編號爲1的第一行。 With ties返回所有的。哦應用技工的喜悅!

+0

這是真棒,但怎麼來的,我不能做的事:「選擇頂部1與領帶 的MessageID, MessageSent, MessageSenderUserID, MessageRecipientUserID 從[Messaging_Message] ORDER BY MessageSent ... '@NikolaMarkovinović – Hoppe 2012-04-04 13:10:09

+1

因爲MessageSent對於不同的MessageSenderUserID具有不同的值。 ROW_NUMBER()指定1到每個最上面MessageSent,由遞減順序翻譯成茨自己的位置,然後登頂1的關係,選擇具有ROW_NUMBER = 1,這是一個特殊的情況下,你甚至不能說選擇頂部2 ......它只能行僅限每組最高價值。 – 2012-04-04 13:23:18

0

這假設用戶不能在完全相同的時間發送多個消息(它會顯示在這種情況下,用戶不止一個消息):

SELECT a.MessageID, a.MessageSent, a.MessageSenderUserID, a.MessageRecipientUserID 
FROM Messaging_Message AS a 
    JOIN (
     SELECT MessageSenderUserID, MAX(MessageSent) AS MessageSent 
     FROM Messaging_Message 
     GROUP BY MessageSenderUserID 
    ) AS b ON a.MessageSenderUserID = b.MessageSenderUserID 
     AND a.MessageSent = b.MessageSent 
1
WITH TestTableCTE AS 
(
    SELECT RN = ROW_NUMBER() OVER(PARTITION BY MessageSenderUserID ORDER BY MessageSent DESC), 
      MessageID, MessageSent, MessageSenderUserID, MessageRecipientUserID 
    FROM [Messaging_Message] 
) 

SELECT MessageID, MessageSent, MessageSenderUserID, MessageRecipientUserID FROM TestTableCTE WHERE RN=1 
+0

如果我把where子句的選擇中with語句每個用戶進行區分,然後有併發用戶訪問,我將有問題?我是新來的臨時結果集 – Hoppe 2012-04-04 13:21:00