2014-03-26 50 views
0

我從兩個表中獲取用戶的聊天消息,因此我使用inner join來實現此目的。這裏是我的SQL查詢:組中的SQL查詢錯誤按訂單條款順序

SELECT 
    m.Message_Id 
    , m.Chat_Relation_Id AS relation_id 
    , m.SenderId AS datetime 
    , m.Text_Message 
    , m.Subject 
    , m.DateTime 
FROM 
    [AppResource].[dbo].[ChatMessage] AS m 
    INNER JOIN [AppResource].[dbo].[chatRelation] AS r 
    ON r.Chat_Relation_Id = m.Chat_Relation_Id 
WHERE 
    r.User1Id=1 
GROUP BY 
    m.Chat_Relation_Id 
ORDER BY 
    m.DateTime DESC 

但是,當我運行這個,我收到以下錯誤消息:

列「AppResource.dbo.ChatMessage.Message_Id」在選擇列表中無效因爲它不包含在聚合函數或GROUP BY子句中。

我在谷歌上搜了很多,發現很多解決方案,但沒有任何作品。 Text_Messagetext數據類型,而DateTimeDatetime數據類型。

請幫我吧。

Message_Id relation_id datetime Text_Message Subject DateTime 
4 1 2 Hello Hi 2014-11-25 00:00:00.000 
8 25 1 hiii ho 2014-03-26 09:07:27.000 
7 26 1  hiiiiii 2014-03-26 07:07:27.000 
6 25 1  hi 2014-03-26 07:01:58.000 
+1

那麼 - 當使用group by時,您不能選擇不屬於group by子句或聚合函數的部分。而Message_Id不是你的組的一部分,也不是一個聚合函數。 (而且這兩個數字都不是你選擇的其他列) –

+0

你能解釋一下你想要達到什麼嗎? – Szymon

+0

但是,當我添加所有列進來選擇然後它給出了文本數據類型的錯誤。你能告訴我該怎麼辦? –

回答

1

當您使用GROUP BY你通常會有aggregate functions,你提供的實際上並沒有在任何聚合函數的SQL所以沒有必要爲它進行分組。

SELECT 
    m.Message_Id 
    , m.Chat_Relation_Id AS relation_id 
    , m.SenderId AS datetime 
    , m.Text_Message 
    , m.Subject 
    , m.DateTime 
FROM 
    [AppResource].[dbo].[ChatMessage] AS m 
    INNER JOIN [AppResource].[dbo].[chatRelation] AS r 
    ON r.Chat_Relation_Id = m.Chat_Relation_Id 
WHERE 
    r.User1Id=1 
GROUP BY 
    m.Chat_Relation_Id 
ORDER BY 
    m.DateTime desc 

錯誤被拋出,因爲所有的非聚合列必須在GROUP BY子句中被定義爲這定義了其他(聚集)列是如何計算的。在你的例子中,並給出所描述的問題,我猜只是刪除GROUP BY將解決你的問題。評論關於重複條目後

SELECT 
    m.Message_Id 
    , m.Chat_Relation_Id AS relation_id 
    , m.SenderId AS datetime 
    , m.Text_Message 
    , m.Subject 
    , m.DateTime 
FROM 
    [AppResource].[dbo].[ChatMessage] AS m 
    INNER JOIN [AppResource].[dbo].[chatRelation] AS r 
    ON r.Chat_Relation_Id = m.Chat_Relation_Id 
WHERE 
    r.User1Id = 1 
ORDER BY 
    m.DateTime DESC 

編輯:

下面的查詢將獲得最新的每個Chat_Relation_Id

SELECT 
    m.Chat_Relation_Id AS relation_id 
    , MAX(m.DateTime) AS maxDateTime 
FROM 
    [AppResource].[dbo].[ChatMessage] AS m 
    INNER JOIN [AppResource].[dbo].[chatRelation] AS r 
    ON r.Chat_Relation_Id = m.Chat_Relation_Id 
WHERE 
    r.User1Id = 1 
GROUP BY 
    m.Chat_Relation_Id 

這是很不理想的條目,但可以作爲子查詢選擇相關文字如下:

SELECT 
    m.Message_Id 
    , m.Chat_Relation_Id AS relation_id 
    , m.SenderId AS datetime 
    , m.Text_Message 
    , m.Subject 
    , m.DateTime 
FROM 
    (SELECT 
     subqueryMessage.Chat_Relation_Id AS relation_id 
     , MAX(subqueryMessage.DateTime) AS maxDateTime 
    FROM 
     [AppResource].[dbo].[ChatMessage] AS subqueryMessage 
     INNER JOIN [AppResource].[dbo].[chatRelation] AS subQueryRelation 
     ON subQueryRelation.Chat_Relation_Id = subqueryMessage.Chat_Relation_Id 
    WHERE 
     subQueryRelation.User1Id = 1 
    GROUP BY 
     subqueryMessage.Chat_Relation_Id 
    ) AS mySubQuery 
    INNER JOIN [AppResource].[dbo].[ChatMessage] AS m 
    ON m.Chat_Relation_Id = mySubQuery.relation_id 
     AND m.DateTime = mySubQuery.maxDateTime 
ORDER BY 
    m.DateTime DESC 

我不喜歡使用這樣的子查詢,但我是一個開發人員而不是DBA,並且上面的限制是,如果有相同的項目Chat_Relation_IdDateTime那麼重複仍然會發生。使用HAVING Clause可能會有一個聰明的方法,但希望如果這不能讓你從中解決問題,將有助於其他人解決您的問題。

+0

但是您編輯的查詢將爲Chat_Relation_Id提供重複結果。我只需要對應於每個Chat_Relation_Id的最近條目。我該如何修改? –

+0

你究竟想要返回什麼?可能值得用[SQL Fiddle](http://sqlfiddle.com/)或詳細的數據結構來更新你的問題,以及你試圖返回的結果,我想我有一個想法並且會發布它當我解決這個問題時,如果你在你的問題中提供了更詳細的要求,你可能會得到更多的幫助(包括來自其他成員)。 – talegna

+0

我已經爲你更新了我的問題。請查看它。 Chat_Relation_Id有多個條目,但具有不同的DateTime。所以,我只需要每個Chat_Relation_Id的最上面的行,即每個關係id的最新聊天消息。 –