【问题标题】:mysql join table and search for most recent record on where clausemysql连接表并搜索where子句的最新记录
【发布时间】:2020-07-31 11:23:31
【问题描述】:

我有两张桌子

  • 用户:ID、电子邮件、名字、姓氏
  • 订阅:id、userId、currentPeriodStart、currentPeriodEnd

下面只是向您展示这两个表是如何相关的。我想退回在 1565827199 之后过期的订阅,但它需要检查每个用户最近的订阅。

select 
u.id 
from users u 
join subscriptions s on u.id s.userId 
where s.currentPeriodEnd > 1565827199 
ORDER BY u.lastName ASC

一个用户可能在订阅表中有多个订阅。我需要做的是修改上面的查询,因此它会检查该用户的最新订阅,而不是它找到的第一个订阅。

select * from subscriptions ORDER BY currentPeriodEnd DESC LIMIT 1

我已经尝试了一些不同的东西(别名表、子查询),但我在 stackoverflow 的其他地方没有任何运气。

【问题讨论】:

    标签: mysql sql date greatest-n-per-group mysql-5.7


    【解决方案1】:

    加入一个子查询,获取每个用户的最新时间,并将其过滤到指定时间戳之后的时间。

    select u.id 
    from users u 
    join (
        select userid
        FROM subscriptions
        GROUP BY userid
        HAVING MAX(currentPeriodEnd) > 1565827199 
    ) s ON s.userid = u.id
    ORDER BY u.lastName ASC
    

    【讨论】:

      【解决方案2】:

      您可以使用相关子查询进行过滤,如下所示:

      select u.*, s.*
      from users u 
      inner join subscriptions s on u.id = s.userId 
      where s.currentPeriodEnd = (
          select max(s1.currentPeriodEnd) 
          from subscriptions s1 
          where s1.userId = u.id and s1.currentPeriodEnd > 1565827199
      )
      order by u.lastName
      

      为了提高性能,请考虑在subscriptions(userId, currentPeriodEnd) 上建立索引。

      或者,如果您运行的是 MySQL 8.0,您可以使用row_number()

      select *
      from (
          select 
              u.*, 
              s.*, 
              row_number() over(partition by u.id order by s.currentPeriodEnd desc)
          from users u 
          inner join subscriptions s on u.id = s.userId 
          where s.currentPeriodEnd > 1565827199
      ) t
      where rn = 1
      order by lastName
      

      【讨论】:

        猜你喜欢
        • 2011-12-25
        • 2021-04-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-10
        相关资源
        最近更新 更多