除了其他答案,这里还有几个其他选项:
选项 1
您可以创建 2 个 CTE,每个月一个(假设您查看的是特定月份,而不仅仅是一般的 2 月/3 月)。请注意,这使用range 数据类型来过滤日期。
WITH
-- sample data
Subscriptions("id", user_id, starts_at, ends_at) AS
(
VALUES
(1, 233, DATE'02/04/19', DATE'03/03/19'),
(2, 233, DATE'03/04/19', DATE'04/03/19'),
(3, 296, DATE'02/09/19', DATE'03/08/19'),
(4, 126, DATE'02/01/19', DATE'02/28/19'),
(5, 126, DATE'03/01/19', DATE'03/31/19'),
(6, 922, DATE'02/22/19', DATE'03/22/19')
),
-- separate CTEs for February and March data
-- using range type for easy filter.
FebruarySubscriptions AS
(
SELECT * FROM Subscriptions
WHERE daterange('2019-02-01', '2019-03-01') @> starts_at
),
MarchSubscriptions AS
(
SELECT * FROM Subscriptions
WHERE daterange('2019-03-01', '2019-04-01') @> starts_at
)
SELECT *
FROM FebruarySubscriptions
LEFT JOIN MarchSubscriptions ON
MarchSubscriptions.user_id = FebruarySubscriptions.user_id
WHERE MarchSubscriptions."id" IS NULL
选项 2
使用LEAD 窗口函数找出哪些用户没有重新订阅。此选项的好处是可扩展性更强。
WITH
Subscriptions("id", user_id, starts_at, ends_at) AS
(
VALUES
(1, 233, DATE'02/04/19', DATE'03/03/19'),
(2, 233, DATE'03/04/19', DATE'04/03/19'),
(3, 296, DATE'02/09/19', DATE'03/08/19'),
(4, 126, DATE'02/01/19', DATE'02/28/19'),
(5, 126, DATE'03/01/19', DATE'03/31/19'),
(6, 922, DATE'02/22/19', DATE'03/22/19')
),
Resubscriptions(user_id, current_subscription, next_subscription) AS
(
SELECT
user_id,
starts_at,
LEAD(starts_at) OVER
(
PARTITION BY user_id
ORDER BY starts_at ASC
)
FROM Subscriptions
)
SELECT *
FROM Resubscriptions
WHERE
daterange('2019-02-01', '2019-03-01') @> current_subscription
AND next_subscription IS NULL