在基于子项的查询中选择前n个父项

时间:2014-09-25 08:39:21

标签: sql sql-server

我想限制这个基于子表的查询返回的父项数。

SELECT
    ch.Id AS childId,
    pr.Id AS parentId
FROM childTable ch
INNER JOIN parentTable pr ON ch.Id = pr.Id
WHERE
    1 = 1
ORDER BY pr.CreatedDate DESC

这应该是一个共同的需要,但我找不到合适的词来形容它。

我必须返回由where语句过滤的子记录,但是限制查询返回的父项数。

就像,给我看孩子的记录......,用父母创建的日期命令他们,只得到前n个父母的子记录。

我试图获取行号,但它计算了孩子的数量

 ...ROW_NUMBER() OVER (PARTITION BY pr.Id ORDER BY pr.CreatedDate DESC) AS Row,
...

我试图按父母对记录进行分组,但后来我从子表中丢失了我需要的详细信息。

我正在使用MS-SQL 2008

修改

以下是demo

关于演示的说明: PostAttachments 是我之前提到的子表帖子 Parent

目录表刚刚为where语句加入,并从该表中获取了一些列。但是值得将它添加到ContentId的演示中,它是PostAttachments 中复合键的一部分。

修改

前2个帖子的预期输出(PostAttachment.xxxx = xxxx):

请说明以下列表中的行(1,3,5,7,8,9)的where语句为真......

(行行仅用于解释,不在数据库中)

[Line]  POSTID  CONTENTID   CREATEDDATE                         TITLE   CONTENTTITLE
1       1       1           September, 25 2014 09:22:27+0000    post1   content1
2       2       2           September, 25 2014 09:22:27+0000    post2   content2
3       3       3           September, 25 2014 09:22:27+0000    post3   content3
4       4       4           September, 25 2014 09:22:27+0000    post4   content4
5       5       5           September, 25 2014 09:22:27+0000    post5   content5
6       1       6           September, 25 2014 09:22:27+0000    post1   content6
7       2       7           September, 25 2014 09:22:27+0000    post2   content7
8       3       8           September, 25 2014 09:22:27+0000    post3   content8
9       4       9           September, 25 2014 09:22:27+0000    post4   content9

所以结果会有PostId为1,3,5,2,3,4的行,但我只想要由TITLE排序前2位

此条件下的预期输出应该有post1和post2 ......

[Line]  POSTID  CONTENTID   CREATEDDATE                         TITLE   CONTENTTITLE
1       1       1           September, 25 2014 09:22:27+0000    post1   content1
2       2       2           September, 25 2014 09:22:27+0000    post2   content2
6       1       6           September, 25 2014 09:22:27+0000    post1   content6
7       2       7           September, 25 2014 09:22:27+0000    post2   content7

铊;博士;我需要通过this demo

中的语句减少额外的位置和顺序

1 个答案:

答案 0 :(得分:0)

我认为这就是你想要的。

SELECT
    pr.PostId AS POSTID
    ,Contents.ContentId
    ,ch.CreatedDate
    ,pr.Title AS Title
    ,Contents.ContentTitle
FROM PostAttachments ch
INNER JOIN Posts pr ON ch.PostId = pr.PostId
INNER JOIN Contents ON ch.ContentId = Contents.ContentId
INNER JOIN (
    SELECT TOP 2 PostId
    FROM PostAttachments
    GROUP BY PostId
    ) t ON ch.PostId = t.PostId

还在小提琴中进行了测试。

<强>被修改

根据进一步的讨论。在小提琴中检查以下查询。

SELECT TOP 4 *
FROM (
    SELECT pr.PostId AS POSTID
        ,Contents.ContentId
        ,ch.CreatedDate
        ,pr.Title AS Title
        ,Contents.ContentTitle
        ,Contents.ContentType
    FROM PostAttachments ch
    INNER JOIN Posts pr ON ch.PostId = pr.PostId
    INNER JOIN Contents ON ch.ContentId = Contents.ContentId
    INNER JOIN (
        SELECT PostId
        FROM PostAttachments
        GROUP BY PostId
        ) t ON ch.PostId = t.PostId
    ) a
WHERE a.ContentType = 0
ORDER BY a.Title DESC
    ,a.ContentId ASC