【问题标题】:How can I retrieve the latest subscription for each user?如何检索每个用户的最新订阅?
【发布时间】:2022-01-22 17:58:04
【问题描述】:

例如我们有 2 个表:

TABLE users WITH FIELDS
    id

TABLE providers WITH FIELDS
    id

TABLE subscriptions WITH FIELDS
    id
    start_date
    provider_id - OneToMany
    user_id - OneToMany

还有下面的sql语句:

SELECT subscription.id
FROM subscriptions
INNER JOIN providers ON 
    subscriptions.provider_id = providers.id AND
    providers.id = 2
INNER JOIN (
    SELECT user_id, MAX(start_date) AS start_date
    FROM subscriptions GROUP BY user_id
) AS max USING (user_id, start_date)

结果,我想为每个用户获取 provider 为(在本例中)为 2 且具有最新 start_datesubscription . 在这种情况下,我们使用provider_id 2,但该值是动态的。

我希望第二个 INNER JOIN 中的 MAX 只接受零售商为 2 的订阅,但事实并非如此,它会接受所有订阅。这是为什么呢?

提前致谢。

【问题讨论】:

  • 第二次加入的 ON 子句在哪里?应该使用哪个字段来连接两个数据源?
  • 您的架构可能存在设计问题。
  • @heximal 我使用 USING 而不是 ON
  • 将开始日期存储在记录中是不够的,您还需要存储结束日期,否则无论您是否意识到,您最终都会计算每个查询的结束日期。在这种情况下,您的问题是因为您没有简单的方法来计算订阅是否“现在”仍然有效 - 因为您需要那个结束日期。尝试查找最晚的开始日期可以替代缺少的结束日期。
  • @TimBiegeleisen 这就像我的实际数据库模式的更简单版本,昨天我开始使用 MAX 和 USING 的 INNER JOIN 来寻找解决方案,我对这些场景还是新手。跨度>

标签: sql postgresql join inner-join


【解决方案1】:

问:我希望第二个 INNER JOIN 中的 MAX 只接受零售商为 2 的订阅,但事实并非如此,它接受了所有订阅。为什么会这样?

这个带有 MAX 的子查询是自包含的。如果您将其作为独立查询执行:

SELECT user_id, MAX(start_date) AS start_date
    FROM subscriptions GROUP BY user_id

那么您会期望它返回每个 user_id 及其 max(start_date),独立于 provider_id 字段,因为该查询中从未提及它。

当它在较大的查询中作为子查询运行时,它会返回完全相同的结果。

您可以将条件 WHERE provider_id=2 添加到该子查询中。

【讨论】:

  • 哦,原来如此,谢谢。但是还有一件事,这样做不好吗?如果是,是否有更好的方法?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-04-01
  • 2016-01-04
  • 1970-01-01
  • 2016-12-16
  • 1970-01-01
  • 2018-12-09
  • 2015-05-06
相关资源
最近更新 更多