从SQL Server中的相关表中获取一定数量的结果

时间:2012-03-04 18:33:29

标签: sql sql-server sql-server-2008 tsql join

我有帖子和评论表:

Post (id, title)
Comment(id, postid, comment, commentdate)

我正在尝试选择最近10条评论日期评论的帖子。得到这个的查询是什么?

示例:

如果我想获得最新的3个帖子:

Post
---
1 P1
2 P2
3 P3
4 P4

Comment
---
1 1 C1 01:01
2 3 C2 01:02
3 3 C3 01:03
4 2 C4 01:04
5 2 C5 01:05
6 1 C6 01:06
7 4 C7 01:07
8 4 C8 01:08

Exptected result:
---

4 P4 01:08
1 P1 01:06
2 P2 01:05

从最后一条记录中搜索评论表,在postid列中,我分别找到4,1和2(并且与众不同)。我找到了3条评论,我就此止步。

3 个答案:

答案 0 :(得分:2)

我认为最简单的万无一失的方法是这样的:

SELECT TOP 10
       id,
       title,
       (SELECT MAX(commentdate)
          FROM comment
         WHERE postid = post.id
       ) AS commentdate
  FROM post
 ORDER BY commentdate DESC
;

但我不希望它表现得很好。 (它为每个帖子找到最新的评论,然后用它来查找最近评论最近的10个帖子。)

一种表现更好的方式,但在某些情况下可能包含少于10个结果的风险,将是这样的:

SELECT TOP 10
       id,
       title,
       (SELECT MAX(commentdate)
          FROM comment
         WHERE postid = post.id
       ) AS commentdate
  FROM post
 WHERE id IN
        ( SELECT TOP 100
                 postid
            FROM comment
           ORDER BY commentdate DESC
        )
 ORDER BY commentdate DESC
;

查找最近100条评论所属的帖子 - 最多100条帖子 - 然后将上述方法应用于这些帖子。 (它可能返回少于10个帖子的原因是,最近的100条评论可能只属于9个帖子 - 或者只有5个帖子,或者只有一个帖子。)

(免责声明:我尚未测试上述任何一种查询。)

答案 1 :(得分:1)

尝试:

SELECT      TOP 3 Post.postId
            , Post.post
            , latestComment.leftAt
FROM        Post
            INNER JOIN (
                SELECT      postId
                            , MAX(leftAt) AS leftAt
                FROM        Comment
                GROUP BY    postId
            ) AS latestComment
              ON    Post.postId = latestComment.postId
ORDER BY    latestComment.leftAt DESC
            , Post.postId

工作SQLFiddle

答案 2 :(得分:0)

DECLARE @n INT = 3; -- or 10, or whatever

;WITH x AS
(
    SELECT
        postid, commentdate,
        rn = ROW_NUMBER() OVER (ORDER BY commentdate DESC)
      FROM dbo.comment AS c
), y AS 
(
  SELECT postid, rn = MIN(rn) FROM x
  GROUP BY postid
)
SELECT TOP (@n) p.postid, p.title, x.commentdate
FROM x INNER JOIN y ON x.rn = y.rn
INNER JOIN dbo.post AS p ON p.postid = x.postid
ORDER BY x.commentdate DESC;

或稍微简单:

DECLARE @n INT = 3; -- or 10, or whatever

;WITH x AS 
(
    SELECT TOP (@n) postid, t = MAX(commentdate)
    FROM dbo.comment
    GROUP BY postid ORDER BY t DESC
)
SELECT p.postid, p.title, commentdate = x.t 
FROM x INNER JOIN dbo.post AS p ON x.postid = p.postid
ORDER BY x.t DESC;