我在PosgreSQL数据库中有一个包含激活订阅数据的表.该表具有以下列:用户ID、订阅开始日期、订阅结束日期和订阅类型.
如果订阅当前处于活动状态,则订阅的结束日期设置为今天的日期.
订阅有两种独立的类型:1.高级订阅,2.图书订阅.它们是独立激活的.例如,数据可能如下所示:
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 |
我需要的是调整溢价订阅的期限,如果另一个订阅(图书)在其期限内被激活.换句话说,高级订阅应该在图书订阅激活之前和之后分为几个阶段.所需的输出将如下所示:
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 |
Made smth like this,but it splits the first subscription named premium into period before the next sub"books".但我不明白如何继续子"溢价"后,"书"完成.
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;