PostgreSQL中拆分Premium订阅期适配Books订阅的技术求助
PostgreSQL订阅数据拆分问题
数据表说明
- 表名:
subscriptions(已激活订阅数据表) - 字段:
User ID:用户IDStart Date of Subscription:订阅开始日期End Date of Subscription:订阅结束日期(当前处于激活状态的订阅,结束日期设为当日)
- 订阅类型:
Premium、Books,二者可独立激活
示例数据
| User ID | Start Date of Subscription | End Date of Subscription | Type of Subscription |
|---|---|---|---|
| 675 | 2023-01-01 | 2023-05-10 | Premium |
| 675 | 2023-02-15 | 2023-02-28 | Books |
| 675 | 2023-04-18 | 2023-06-18 | Books |
| 726 | 2023-01-01 | 2023-10-10 | Premium |
| 726 | 2023-03-16 | 2023-05-28 | Books |
| 855 | 2023-04-05 | 2023-05-28 | Books |
| 855 | 2023-04-20 | 2023-07-25 | Premium |
需求说明
当Books订阅在Premium订阅有效期内激活时,需将Premium订阅拆分为Books订阅开始前、Books订阅结束后的多个时段,期望输出如下:
| User ID | Start Date of Subscription | End Date of Subscription | Type of Subscription |
|---|---|---|---|
| 675 | 2023-01-01 | 2023-02-15 | Premium |
| 675 | 2023-02-15 | 2023-02-28 | Books |
| 675 | 2023-02-28 | 2023-04-18 | Premium |
| 675 | 2023-04-18 | 2023-06-18 | Books |
| 726 | 2023-01-01 | 2023-03-16 | Premium |
| 726 | 2023-03-16 | 2023-05-28 | Books |
| 726 | 2023-05-28 | 2023-10-10 | Premium |
| 855 | 2023-04-05 | 2023-05-28 | Books |
| 855 | 2023-05-28 | 2023-07-25 | Premium |
现有代码问题
我编写了如下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,提问作者Кирилл
相关产品推荐
相关产品推荐

