【问题标题】:SQL Select newest (public) post of each userSQL 选择每个用户的最新(公开)帖子
【发布时间】:2021-07-06 21:25:24
【问题描述】:

数据示例如下:

username tweet is_public created_at
catelie tweet1 1 2021-06-14
urs tweet1 1 2021-06-15
nik firstlast 1 2021-06-15
urs lasttweet 1 2021-06-23
nik empty 0 2021-06-23

选择所有公开推文

 WHERE is_public = 1 

要选择每个用户的最新推文我受到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

要选择每个用户的最新和公开推文(混淆这两个语句)我迷失了一些 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 选择正确(双打中的空实体),但这是唯一正确的选择。请帮我调试一下。thx^^lg

【问题讨论】:

  • 。 .我对您的问题与您提出的问题有什么关系感到有些困惑。
  • 我的查询包含“每个用户的最新推文”(来自我发布的链接,其中包含“p1.created_at

标签: sql subquery unique


【解决方案1】:

你把这件事复杂化了。您可以使用关联子查询,但不需要额外的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) 上建立索引。

【讨论】:

  • thx,我开始爱上 stackoverflow 了 :) 我会尽快将你的答案标记为 cvorrect 我被允许标记它(我太新了,现在无法标记或投票)
  • 根据您的回答,我“更正”了我的代码: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.username = postdouble.username AND posts.created_at
  • @DarioDS 。 . .这个答案没有JOIN
  • 是的,而且您的回答也不包含 GROUP BY()。 (与上面链接的标记为“正确”的解决方案相比)。我刚刚发布了我的“工作代码”,与您的较短答案进行了全面比较(似乎两者都以 +-10% 的速度运行,并且肯定我在我的作品中添加了您的缩短)!再次感谢(我现在能够将您的答案标记为正确的答案)^^lg
  • 我认为它们以相同的速度运行,因为所有标准(例如 is_public = 1)需要列出两次(在我的代码和您的缩短中)。或者是否有一个解决方案(没有“窗口功能”也没有“前 1 个有关系”),您只需列出一次“is_public = 1”?
【解决方案2】:

另一种简单的方法是使用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

【讨论】:

    猜你喜欢
    • 2012-07-28
    • 2011-10-11
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 2011-09-13
    • 2013-06-17
    • 1970-01-01
    • 2016-04-24
    相关资源
    最近更新 更多