sql - 以 12 个月滚动的方式遍历客户,并检查客户在过去 12 个月内是否未订购
问题描述
CREATE TABLE customers (
id SERIAL PRIMARY KEY,
order_date DATE,
customer VARCHAR(255)
);
INSERT INTO customers
(order_date, customer)
VALUES
('2020-03-10', 'user_01'),
('2020-03-18', 'user_02'),
('2020-03-26', 'user_03'),
('2020-04-12', 'user_04'),
('2020-04-19', 'user_05'),
('2020-04-23', 'user_06'),
('2021-03-09', 'user_01'),
('2021-03-17', 'user_07'),
('2021-04-03', 'user_02'),
('2021-04-18', 'user_05'),
('2021-04-20', 'user_08');
预期结果:
churn_date | customer |
--------------|--------------|----
2021-03-18 | user_02 |
2021-03-26 | user_03 |
--------------|--------------|-----
2021-04-12 | user_04 |
2021-04-23 | user_06 |
我想在12 个月滚动的基础上遍历客户,并检查每个月客户的最后一个订单是否是在 12 个月前下达的。
例如:
user_02
应该出现在 的结果中March
但不应该出现在 的结果中April
。
鉴于上March
一次订单发生在 12 个月前2020-03-18
。
在视图April
上发生的最后一个命令2021-04-03
。
在一个月内,我可以通过以下查询来做到这一点:
SELECT
(c1.order_date + interval '12 month')::date as churn_date,
c1.customer
FROM customers c1
WHERE c1.order_date BETWEEN '2020-03-01 00:00:00' AND '2020-03-31 23:59:59'
AND NOT EXISTS
(SELECT
c2.customer
FROM customers c2
WHERE c2.order_date BETWEEN '2020-04-01 00:00:00' AND '2021-03-31 23:59:59'
AND c2.customer = c1.customer)
ORDER BY 1,2;
但是,我必须为每个月单独运行此查询。
因此,我想知道是否有一个迭代解决方案可以一次经历多个月并给我预期的结果?
解决方案
这是上一个带有WHERE
子句的查询:
SELECT gs.month, c.customer, MAX(c.order_date + interval '12 month')::date as churn_date
FROM customers c CROSS JOIN
GENERATE_SERIES('2021-03-01'::date, '2021-04-01'::date, interval '1 month') gs(month)
WHERE c.order_date < gs.month + interval '1 month'
GROUP BY gs.month, c.customer
HAVING DATE_TRUNC('month', MAX(c.order_date)) = DATE_TRUNC('month', gs.month) - interval '12 month';
这是一个 db<>fiddle。
推荐阅读
- c++ - 如何仅使用 2 个参数在 C++ 中制作递归字符串检测器
- github - 当我尝试将新更改推送到 github 时出现“无法将一些参考推送到 github”错误
- haskell - 无法将预期类型“SomeEntity”与实际类型“Key SomeEntity”匹配
- wordpress - 使用 Stripe Checkout 实现自定义捐赠金额
- python - 无法抓取图像 URL(Scrapy)
- java - 如何在 Java Android Studio 中验证日月和年,
- python - 使用 groupby 对时间序列数据进行多项数学运算
- apache-spark - Kubernetes 上的 Spark:驱动程序死亡 -> 执行程序命中自毁序列但不会死亡
- ios - iOS App:React-Native加载在App中加载一段时间后停止加载
- express - RESTDataSource - 如何知道响应来自获取请求还是缓存