SQL查询:如何获取用户及其三个最新帖子?

时间:2014-07-26 16:14:03

标签: sql greatest-n-per-group

假设我有一个简单的两个表格架构userspostsposts表有一个指向users的外键,指示谁创作了该帖子。

另外,假设我想列出用户及其最近的3篇帖子。我可以在O(n)查询中执行此操作(1列出用户,1表示每个用户获得他们的帖子),但我如何在O(1)查询中执行此操作?

要么一次获取用户和帖子的一个查询,要么获得2个查询,一个用于获取用户,一个用于获取帖子。假设我将重复删除任何重复的用户数据。

4 个答案:

答案 0 :(得分:4)

您没有说明您的DBMS,因此这是ANSI SQL(受各种DBMS支持):

select *
from (
   select u.username,
          p.title, 
          row_number() over (partition by u.id order by p.post_time desc) as rn
   from users u
     join posts p on u.id = p.user_id
) t
where rn <= 3
order by u.username;

答案 1 :(得分:1)

以下内容适用于任何数据库:

select u.username, p.title, p.post_time
  from users u
  join posts p
    on u.id = p.user_id
 where p.post_time >=
       (select max(z.post_time)
          from posts z
         where z.user_id = p.user_id
           and z.post_time <
               (select max(y.post_time)
                  from posts y
                 where y.user_id = p.user_id
                   and y.post_time <
                       (select max(x.post_time)
                          from posts x
                         where x.user_id = p.user_id)))

答案 2 :(得分:1)

应该适用于大多数数据库的自联接。这假定每个用户post_time是唯一的。如果不是这样,那么您可以将on p2.post_time >= p.post_time替换为on p2.id >= p.id

select u.username, p.id, p.title
from user u join
(
    select p.id, p.title, p.user_id 
    from posts p join posts p2
    on p2.user_id = p.user_id
    and p2.post_time >= p.post_time
    group by p.id, p.title, p.user_id
    having count(*) <= 3
) p on u.id = p.user_id

答案 3 :(得分:0)

SELECT *
FROM Users a
CROSS APPLY (
SELECT TOP 3 *
FROM posts z
WHERE a.User_ID = z.User_ID
ORDER BY z.post_time DESC
) b