Group By和Order By子句中的SQL查询错误

时间:2014-03-26 08:50:14

标签: sql sql-server sql-server-2008

我从两个表中收到用户的聊天消息,因此我使用了inner join。这是我的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子句中。

我在google上搜索了很多,发现了很多解决方案,但没有任何效果。 Text_Message的数据类型为textDateTime的数据类型为Datetime

请帮助我。

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 个答案:

答案 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来完成它,但希望如果这不会给你一些工作,它将帮助其他人解决你的问题。