使用此SQL语句按用户名分组的最佳方式是什么?
我想显示一个消息历史记录,其中最新消息首先按用户名分组 当我使用GROUPBY方法时,它告诉我需要添加所有其他列使用此SQL语句按用户名分组的最佳方式是什么?,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,我想显示一个消息历史记录,其中最新消息首先按用户名分组 当我使用GROUPBY方法时,它告诉我需要添加所有其他列 列“Messages.FromUserID”在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中。 一定有更好的方法吗?使用行号()覆盖(按M.FromUserID按M.ViewedDate DESC划分): 可能通过使用窗口功能,如行数()。一些示例数据会有所帮助。您希望看到哪些数据?按用户名分组意味着每个用户名只需要一行,而不是更多。也许您首先需要的是按用户名排序?是
列“Messages.FromUserID”在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中。
一定有更好的方法吗?使用行号()覆盖(按M.FromUserID按M.ViewedDate DESC划分)
:
可能通过使用窗口功能,如
行数()
。一些示例数据会有所帮助。您希望看到哪些数据?按用户名分组意味着每个用户名只需要一行,而不是更多。也许您首先需要的是按用户名排序?是的,我想查看按消息来源的人分组的消息,最新的消息位于顶部。我在该查询中没有看到任何GROUP BY子句。是否存在复制/粘贴错误?您似乎误解了GROUP BY将执行的操作-它将尝试为GROUP BY子句中出现的每个唯一组合只生成一行。因此,根据定义,groupbyusername
将为每个用户名指定一行。然后,您需要为输出列表中显示的其他每一列指定聚合函数,如MIN
、MAX
、SUM
等。为此,这会产生错误“没有为'CTE'的第14列指定列名”。@ChrisDowdeswell:Sorry,通常我会在列名前面加上前缀,而不是在列名后面加上AS
。但在这里我忘记了两者;)(编辑我的答案)
SELECT
M.FromUserID,
UF.Fname + ' ' + UF.Sname As FullName,
UF.URL as Username,
Subject,
Body,
M.Ctime,
M.ViewedDate,
M.MessageID,
M.Starred,
M.Deleted,
M.ToUserID,
(SELECT TOP 1 Fname + ' ' + Sname as FullName FROM user_basics UB WHERE UB.UserID = M.ToUserID) as ToName,
(SELECT TOP 1 URL FROM user_basics UB WHERE UB.UserID = M.ToUserID) as ToUserName
FROM Messages M
LEFT JOIN User_Basics UF ON UF.userID = M.FromUserID
WHERE M.ToUserID = 1433 AND Deleted IS NULL ORDER BY M.Ctime DESC
WITH CTE AS
(
SELECT
M.FromUserID,
UF.Fname + ' ' + UF.Sname As FullName,
UF.URL as Username,
Subject,
Body,
M.Ctime,
M.ViewedDate,
M.MessageID,
M.Starred,
M.Deleted,
M.ToUserID,
(SELECT TOP 1 Fname + ' ' + Sname as FullName FROM user_basics UB WHERE UB.UserID = M.ToUserID) as ToName,
(SELECT TOP 1 URL FROM user_basics UB WHERE UB.UserID = M.ToUserID) as ToUserName,
RN = ROW_NUMBER() OVER (PARTITION BY M.FromUserID ORDER BY M.ViewedDate DESC)
FROM Messages M
LEFT JOIN User_Basics UF ON UF.userID = M.FromUserID
WHERE M.ToUserID = 1433
AND Deleted IS NULL
)
SELECT * FROM CTE
WHERE RN = 1
ORDER BY Ctime DESC