You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL中拆分Premium订阅期适配Books订阅的技术求助

PostgreSQL订阅数据拆分问题

数据表说明

  • 表名:subscriptions(已激活订阅数据表)
  • 字段:
    • User ID:用户ID
    • Start Date of Subscription:订阅开始日期
    • End Date of Subscription:订阅结束日期(当前处于激活状态的订阅,结束日期设为当日)
  • 订阅类型:Premium、Books,二者可独立激活

示例数据

User IDStart Date of SubscriptionEnd Date of SubscriptionType of Subscription
6752023-01-012023-05-10Premium
6752023-02-152023-02-28Books
6752023-04-182023-06-18Books
7262023-01-012023-10-10Premium
7262023-03-162023-05-28Books
8552023-04-052023-05-28Books
8552023-04-202023-07-25Premium

需求说明

当Books订阅在Premium订阅有效期内激活时,需将Premium订阅拆分为Books订阅开始前、Books订阅结束后的多个时段,期望输出如下:

User IDStart Date of SubscriptionEnd Date of SubscriptionType of Subscription
6752023-01-012023-02-15Premium
6752023-02-152023-02-28Books
6752023-02-282023-04-18Premium
6752023-04-182023-06-18Books
7262023-01-012023-03-16Premium
7262023-03-162023-05-28Books
7262023-05-282023-10-10Premium
8552023-04-052023-05-28Books
8552023-05-282023-07-25Premium

现有代码问题

我编写了如下SQL代码,但仅能将Premium订阅拆分为Books订阅开始前的时段,不知道如何实现Books订阅结束后继续Premium订阅的逻辑:

WITH ordered_subscriptions AS (
    SELECT *,
           ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY start_date) as rn
    FROM subscriptions
),
date_ranges AS (
    SELECT 
        a.user_id, 
        a.start_date, 
        MIN(b.start_date) as end_date,
        a.subscription_type
    FROM ordered_subscriptions a
    LEFT JOIN ordered_subscriptions b ON a.user_id = b.user_id AND a.rn < b.rn
    GROUP BY a.user_id, a.start_date, a.subscription_type
),
filtered_subscriptions AS (
    SELECT 
        user_id, 
        start_date, 
        COALESCE(end_date, CURRENT_DATE) as end_date, 
        subscription_type
    FROM date_ranges
    WHERE subscription_type = 'Premium' AND NOT EXISTS (
        SELECT 1 
        FROM date_ranges d2 
        WHERE d2.user_id = date_ranges.user_id 
        AND d2.subscription_type = 'Books' 
        AND d2.start_date < date_ranges.end_date 
        AND (d2.end_date IS NULL OR d2.end_date > date_ranges.start_date)
    )
)

SELECT * FROM filtered_subscriptions
UNION ALL
SELECT user_id, start_date, COALESCE(end_date, CURRENT_DATE), subscription_type 
FROM date_ranges 
WHERE subscription_type = 'Books'
ORDER BY user_id, start_date;

内容的提问来源于stack exchange,提问作者Кирилл

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 03:01:06