最后消息发送逻辑问题

时间:2018-08-17 15:46:12

标签: sql sql-server where-clause

我正在尝试为SQL中的一组对话标识对话中发送的最后一条消息。我可以找回正确的用户,而ID没问题,但是两个对话的最后一条消息及其发送的时间都回来了,而我需要在特定对话中发送最后一条消息。

这是我正在使用的SQL:

SELECT ConversationId,
       (SELECT Username FROM dbo.[User] WHERE (UserId = dbo.Conversation.FromUser)) AS FromUser,
       (SELECT Username
        FROM dbo.[User] User_1
        WHERE (UserId = dbo.Conversation.ToUser)) AS ToUser,
       (SELECT TOP (1)
               MessageBody
        FROM dbo.ConversationMessage
        WHERE (ConversationId = ConversationId)
        ORDER BY MessageDateTime DESC) AS LastMessageBody,
       (SELECT TOP (1)
               CONVERT(varchar(5), MessageDateTime, 114) AS Expr1
        FROM dbo.ConversationMessage ConversationMessage_1
        WHERE (ConversationId = ConversationId)
        ORDER BY MessageDateTime DESC) AS LastMessageTime
FROM dbo.Conversation;

这是我要返回的结果集,只是为了清楚起见: enter image description here

LastMessageBody和LastMessageTime应该都是唯一的,并且由于ConversationId都是唯一的,所以我看不到为什么每次都应返回相同的消息。我的理解是,像其他列中的UserId一样,将在where子句中使用单个行的ConversationId?

2 个答案:

答案 0 :(得分:4)

老实说,这在黑暗中是一个巨大的打击,但是,可能是您所追求的。这里没有示例数据或预期结果,因此,如果您不需要这些数据,请同时提供两者。

我也摆脱了那些糟糕的子查询,并用JOIN s代替了它们:

SELECT TOP 1 WITH TIES
       C.ConversationId,
       Uf.Username AS FromUser,
       Ut.Username AS ToUser,
       CM.MessageBody AS LastMessageBody,
       CONVERT(time(0),CM.MessageDateTime) AS LastMessageTime
FROM dbo.[Conversation] C
     JOIN dbo.[User] Uf ON C.FromUser = Uf.UserId
     JOIN dbo.[User] Ut ON C.ToUser = Ut.UserId
     JOIN dbo.ConversationMessage CM ON C.ConversationId = CM.ConversationId
ORDER BY ROW_NUMBER() OVER (PARTITION BY C.ConversationId ORDER BY CM.MessageDateTime DESC);

答案 1 :(得分:0)

每当查询中有多个表时,总是使用表别名和限定的列名。这是你的问题。

以下是解决方法的示例:

SELECT . . .
       (SELECT TOP (1) cm.MessageBody
        FROM dbo.ConversationMessage cm
        WHERE cm.ConversationId = c.ConversationId
        ORDER BY cm.MessageDateTime DESC
       ) AS LastMessageBody,
       . . .
 FROM dbo.Conversation c;

所有列名正确限定后,您的查询应该可以按预期工作。