我正在尝试为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;
LastMessageBody和LastMessageTime应该都是唯一的,并且由于ConversationId都是唯一的,所以我看不到为什么每次都应返回相同的消息。我的理解是,像其他列中的UserId一样,将在where子句中使用单个行的ConversationId?
答案 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;
所有列名正确限定后,您的查询应该可以按预期工作。