联合两个表并仅选择前'n'个记录

时间:2011-02-15 13:18:40

标签: sql sql-server pagination

我正在尝试编写一个社交网络应用程序但我仍然坚持使用墙上的帖子/评论部分。我有两张桌子,帖子评论;

CREATE TABLE [dbo].[COMMENTS](
    [COMMENT_ID] [int] IDENTITY(1,1) NOT NULL,
    [POST_ID] [int] NOT NULL,
    [USER_ID] [smallint] NOT NULL,
    [COMMENT] [nvarchar](max) NOT NULL,
    [CREATED] [datetime]
)
-- COMMENT_ID is PK

CREATE TABLE [dbo].[POSTS](
    [POST_ID] [int] IDENTITY(1,1) NOT NULL,
    [USER_ID] [int] NOT NULL,
    [POST] [nvarchar](max) NOT NULL,
    [CREATED] [datetime]
)
-- POST_ID is PK

我要做的是从 POSTS 表中选择 TOP N 记录,所有评论都属于这些记录。我正在使用以下查询但它选择了来自POSTS和COMMENTS的所有记录,这会因为有太多的POSTS来减慢服务器的速度

SELECT POST_ID, NULL AS COMMENT_ID, USER_ID, POST, CREATED, POST_ID AS SEQUENCE FROM POSTS
UNION
SELECT POST_ID, COMMENT_ID, USER_ID, COMMENT AS POST, CREATED, POST_ID AS SEQUENCE FROM COMMENTS
ORDER BY SEQUENCE DESC

如何选择TOP 10个帖子以及对这些帖子的所有评论?我也想dbpage那些记录,所以也许分页代码对我来说很棒。我的意思是,我想从第2页选择10个帖子及其评论,而不是选择前10个帖子。

我不确定这种表结构是否可行。如果不是,也许你应该给我一个更好的桌面结构。

感谢。

编辑:我希望记录集如下所示。我认为下表比INNER JOIN-ed表更好。我想要的只是 SELECT TOP N POSTS ,仅此而已。

POST_ID     | COMMENT_ID    | USER_ID   | POST                          | CREATED
----------------------------------------------------------------------------------------
3               NULL            2           This post has no comments       2011-02-12
1               NULL            1           A new post                      2011-02-11
1               1               2           Comment for post 1              2011-02-11
1               2               1           Another comment for post 1      2011-02-11
1               5               2           Another comment for post 1      2011-02-11
2               NULL            2           Another post                    2011-02-07
2               3               1           Comment for post 2              2011-02-07
2               4               2           Another comment for post 2      2011-02-07

5 个答案:

答案 0 :(得分:4)

select post_id, comment_id, user_id, post, created
from (
    select top 10 post_id, null as comment_id, user_id, post, created
    from posts
    order by created desc
    ) ss

union

select 
    posts.post_id
    , comment_id
    , comments.user_id
    , comment as post
    , comments.created
from posts
inner join comments on posts.post_id = comments.post_id
where posts.post_id in (
    select top 10 post_id
    from posts
    order by created desc
    )

order by created desc

答案 1 :(得分:0)

UNION(以及UNION ALL)为您提供了两个完全独立的SELECT个查询的综合结果,这些查询可能不是您想要的最后一个代码段。

  

如何选择TOP 10个帖子以及对这些帖子的所有评论?

我认为从INNER JOINPOSTS的简单COMMENTS应该是一个好的开始。但不确定如何在这种情况下最好地实现分页。

答案 2 :(得分:0)

关于分页,我认为您需要使用ROW_NUMBER() - docs - 根据您的POST_ID创建一个计数。这样您就可以在查询时动态选择范围。

希望有所帮助。

答案 3 :(得分:0)

试试这个。

SELECT POST_ID, NULL AS COMMENT_ID, USER_ID, POST, CREATED, POST_ID AS SEQUENCE FROM POSTS
UNION
SELECT POST_ID, COMMENT_ID, USER_ID, COMMENT AS POST, CREATED, POST_ID AS SEQUENCE FROM COMMENTS
ORDER BY SEQUENCE DESC
WHERE (POSTS.POST_ID IN (SELECT TOP (10) POST_ID FROM POSTS as POSTS1))

另外,我不明白为什么你使用Union over Inner Join。您可能也想尝试一下。

答案 4 :(得分:0)

加入两个表并检索前10个记录

从Table1内连接Table2中选择前10 * * Table1.empid = Table2.empid