SQL Select 每个用户的最新 (public) post

SQL Select newest (public) post of each user

数据示例可能如下所示:

用户名 推文 is_public created_at
卡特莉亚 tweet1 1 2021-06-14
tweet1 1 2021-06-15
尼克 头尾 1 2021-06-15
lasttweet 1 2021-06-23
尼克 0 2021-06-23

到select所有public推文:

 WHERE is_public = 1 

至 select 每个用户的最新推文 我受到 these 的启发,所以我得到:

SELECT posts.* FROM post
  LEFT JOIN posts as postdouble
    ON posts.created_at < postdouble.created_at AND posts.username = postdouble.username
WHERE postdouble.username IS NULL

每个用户select最新和public推文(混淆这两个陈述)我' m 被一些 SubSubQueries

丢失了
SELECT posts.username, posts.tweet, posts.is_public, posts.created_at, postdouble.username as userd, postdouble.tweet as tweetd, postdouble.is_public as ispublicd, postdouble.created_at as createdatd FROM posts
  LEFT JOIN posts as postdouble
    ON posts.created_at < (
         SELECT MAX(posts.created_at) FROM posts WHERE is_public = 1
      )
    AND posts.username = postdouble.username
-- WHERE postdouble.username IS NULL

urs selected 正确(双打中的空实体)但这是唯一正确的事情。请帮我一些debugging.thx^^lg

你把这个复杂化了。您可以使用相关子查询,但不需要额外的 JOIN:

SELECT p.*
FROM posts p
WHERE p.created_at = (SELECT MAX(p2.created_at)
                      FROM posts p2
                      WHERE p2.is_public = 1 AND
                            p2.username = p.username
                     ) AND
      p.is_public = 1;

关联子句确保它是针对同一用户的。

为了获得最佳性能,您需要在 posts(username, public, created_at) 上建立索引。

另一种简单的方法是使用 window function 来选择所需的行

select * from (
    select *, Row_Number() over(partition by username order by created_at desc) rn
    from posts
    where is_public=1
)p
where rn=1

在这种情况下,您也可以使用 top 1 with ties

获得相同的结果
select top (1)  with ties *, Row_Number() over(partition by username order by created_at desc) rn
from posts
where is_public=1
order by rn