使用此SQL语句按用户名分组的最佳方式是什么?

使用此SQL语句按用户名分组的最佳方式是什么?,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,我想显示一个消息历史记录,其中最新消息首先按用户名分组 当我使用GROUPBY方法时,它告诉我需要添加所有其他列 列“Messages.FromUserID”在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中。 一定有更好的方法吗?使用行号()覆盖(按M.FromUserID按M.ViewedDate DESC划分): 可能通过使用窗口功能,如行数()。一些示例数据会有所帮助。您希望看到哪些数据?按用户名分组意味着每个用户名只需要一行,而不是更多。也许您首先需要的是按用户名排序?是

我想显示一个消息历史记录,其中最新消息首先按用户名分组

当我使用GROUPBY方法时,它告诉我需要添加所有其他列

列“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