在外键表上排序

时间:2012-12-18 06:31:25

标签: sql sql-server-2008

好的,我正尽力把它尽可能地放在......

我有两个表格messagecomments,其中messageIdcomments中的外键,其中{{1}}是正常关系。

现在在某个屏幕上,我显示当前按其发布日期排序的所有消息。这是扭曲:现在需要的是,尽管显示应该只在应该看到消息的地方显示,但是顺序应该根据消息上发布的最新评论。

示例:

  • 消息1和消息2
  • 消息1发布日期>消息2发布日期
  • 但是message2刚才收到了评论。

在这种情况下,消息2应该在列表顶部,然后消息1

注意:在显示中,我没有提取评论,只是通过postdate显示消息

我希望我说得对。

3 个答案:

答案 0 :(得分:2)

SELECT M.*, C.MostRecent
  FROM Message M
  JOIN (SELECT MessageID, MAX(Comment_DateTime) AS MostRecent
          FROM Comments
         GROUP BY MessageID
       ) AS C ON M.MessageID = C.MessageID
 ORDER BY C.MostRecent DESC

在小桌子上合理地工作。它总结了Comments表,查找每条消息的最新评论,然后按时间戳的降序排序消息。如果桌子很大,它会变慢,特别是如果你只是展示前几个消息。在这种情况下,您希望对查询设置限制,以便比扫描完整的表少得多。例如,您可能猜测您只需要过去一小时,一天或一周的行,而不是所有时间。

即使使用OLAP函数表示法,您仍然需要担心是否可以将查询限制为有用的数据子集。

答案 1 :(得分:1)

有人对此发表了评论,这是不可见的。 这是一个很好的建议。我设法为消息提取最大评论日期,然后在该日期之前订购。

答案 2 :(得分:0)

您可以使用CTE(公用表表达式)和ROW_NUMBER()函数尝试这样的事情:

;WITH CTE AS
(
 SELECT
     m.MessageId, m.MessageText, m.PostedDate,
     CommentDate = ISNULL(c.CommentDate, '19000101'),
     RowNum = ROW_NUMBER() OVER (PARTITION BY m.MessageID 
                                 ORDER BY ISNULL(c.CommentDate, '19000101') DESC) 
 FROM dbo.Messages m
 LEFT OUTER JOIN dbo.Comments c ON c.MessageId = m.MessageId
)
SELECT
   MessageId, MessageText, PostedDate
FROM 
   CTE
WHERE
   RowNum = 1
ORDER BY
   CommentDate DESC

此CTE按MessageID“分区”数据,然后按CommentDate对所有评论(如果有)进行编号。因此,对于每个MessageID,您应该获得连续的RowNum值 - 从最近的评论开始为1。

从此CTE(“临时”内联视图)中,您只需选择具有RowNum = 1的所有行 - 具有最新评论日期的所有行。我也在选择CTE中的CommentDate,因为我认为可能还没有评论,所以我使用ISNULL()函数确保在没有评论的情况下提供ficticiuos评论日期。