假设我有一个简单的两个表格架构users
和posts
。 posts
表有一个指向users
的外键,指示谁创作了该帖子。
另外,假设我想列出用户及其最近的3篇帖子。我可以在O(n)查询中执行此操作(1列出用户,1表示每个用户获得他们的帖子),但我如何在O(1)查询中执行此操作?
要么一次获取用户和帖子的一个查询,要么获得2个查询,一个用于获取用户,一个用于获取帖子。假设我将重复删除任何重复的用户数据。
答案 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