查找过去 X 天内的活跃客户
Posted
技术标签:
【中文标题】查找过去 X 天内的活跃客户【英文标题】:Find Active customers in past X days 【发布时间】:2020-12-17 14:46:43 【问题描述】:我正面临一些困难时期,需要快速帮助。如果有人可以帮助我,那就太好了。 提前非常感谢:)
我有 2 张桌子。 第一张表:daily_customer_snapshot:客户的每日快照,如下图所示。
c_id | date | state | location |
---|---|---|---|
b1 | 2020-12-01 | Active | OOW |
b1 | 2020-12-02 | Active | OOW |
b1 | 2020-12-03 | Active | OOW |
b1 | 2020-12-04 | Active | OOW |
b1 | 2020-12-05 | Active | OOW |
b3 | 2020-12-06 | Active | OOW |
b3 | 2020-12-07 | Active | OOW |
b3 | 2020-12-08 | Active | OOW |
b1 | 2020-12-09 | Decay | IW |
b2 | 2020-12-15 | Active | OOW |
第二个表:customer_date_series:包含从用户成为我们的客户之日起的日期系列。 例如:参考图片 2:用户 b1 在“2020-12-01”成为我们的客户,用户 b3 在“2020-12-06”成为我们的客户 b2 于 '2020-12-15' 成为我们的客户。我已经生成了带有 customer_id 的日期系列,以计算在任何给定日期我们有多少客户。
c_id | date |
---|---|
b1 | 2020-12-01 |
b1 | 2020-12-02 |
b1 | 2020-12-03 |
b1 | 2020-12-04 |
b1 | 2020-12-05 |
b1 | 2020-12-06 |
b1 | 2020-12-07 |
b1 | 2020-12-08 |
b1 | 2020-12-09 |
b1 | 2020-12-10 |
b1 | 2020-12-11 |
b1 | 2020-12-12 |
b1 | 2020-12-13 |
b1 | 2020-12-14 |
b1 | 2020-12-15 |
b1 | 2020-12-16 |
b3 | 2020-12-06 |
b3 | 2020-12-07 |
b3 | 2020-12-08 |
b3 | 2020-12-09 |
b3 | 2020-12-10 |
b3 | 2020-12-11 |
b3 | 2020-12-12 |
b3 | 2020-12-13 |
b3 | 2020-12-14 |
b3 | 2020-12-15 |
b3 | 2020-12-16 |
b2 | 2020-12-15 |
b2 | 2020-12-16 |
我将 table1 (customer_date_series) 与 table2 (daily_customer_snapshot) 连接在一起,以获取任何给定日期的客户行为概览。 我得到了如图 3 所示的结果。
查询加入:
select
bds.date,
bds.c_id,
b.state,
b.location
FROM
customer_date_series bds LEFT JOIN daily_customer_snapshot b ON bds.c_id = b.c_id and bds.date = b.date
ORDER BY
1,2;
date | c_id | state | location |
---|---|---|---|
2020-12-01 | b1 | Active | OOW |
2020-12-02 | b1 | Active | OOW |
2020-12-03 | b1 | Active | OOW |
2020-12-04 | b1 | Active | OOW |
2020-12-05 | b1 | Active | OOW |
2020-12-06 | b1 | ||
2020-12-06 | b3 | Active | OOW |
2020-12-07 | b1 | ||
2020-12-07 | b3 | Active | OOW |
2020-12-08 | b1 | ||
2020-12-08 | b3 | Active | OOW |
2020-12-09 | b1 | Decay | IW |
2020-12-09 | b3 | ||
2020-12-10 | b1 | ||
2020-12-10 | b3 | ||
2020-12-11 | b1 | ||
2020-12-11 | b3 | ||
2020-12-12 | b1 | ||
2020-12-12 | b3 | ||
2020-12-13 | b1 | ||
2020-12-13 | b3 | ||
2020-12-14 | b1 | ||
2020-12-14 | b3 | ||
2020-12-15 | b1 | ||
2020-12-15 | b2 | Active | OOW |
2020-12-15 | b3 | ||
2020-12-16 | b1 | ||
2020-12-16 | b2 | ||
2020-12-16 | b3 |
这是我苦苦挣扎的地方。 我在这里面临挑战。我想创建名为“状态”的新列,如果daily_customer_snapshot 中的客户数据在current_date 的过去5 天内更新 我想将状态设置为“活动”,否则为“不活动”。 前任:
【问题讨论】:
请阅读this,了解一些改进问题的技巧。不要发布数据图像,使用文本。您需要一个适用于mysql
、postgresql
和 tsql
的答案吗?如果没有,则删除不适当的标签。
Postgres 还是 Redshift?尽管它们有着一些古老的渊源,但它们是截然不同的产品。
Redshift 是 @a_horse_with_no_name ,如果有人能给出更优化的解决方案,那就太好了。
【参考方案1】:
如果我没看错,你可以使用布尔窗口聚合:
select
bds.date,
bds.c_id,
b.state,
b.location,
bool_or(b.state = 'Active') over(
partition by bds.c_id
order by bds.date
range between interval '5 days' preceding and current row
) as is_active
from customer_date_series bds
left join daily_customer_snapshot b on bds.c_id = b.c_id and bds.date = b.date
order by 1,2;
这会在同一客户在过去 5 天(或当天)内至少活跃一次的行上设置一个布尔标志。
如果您确实想查看 'Active'
/ 'InActive'
(我发现它不如布尔值有用),您可以这样做:
min(b.state) over(
partition by bds.c_id
order by bds.date
range between interval '5 days' preceding and current row
) as status
... 这行得通,因为字符串方面,'Active' < 'InActive'
。
【讨论】:
嗨@GMB,非常感谢您的帮助。无论客户的状态(不仅需要活跃,也可以衰减)是什么,如果我们在过去 5 天的快照中输入了数据,则 customer_status 设置为“活跃”,否则设置为“不活跃”。对于状态列下的每个电池,我必须为每个日期输入 1 个条目。 @SidduKattimani:所以,我们可以这样做:bool_or(b.c_id is not null) over(...)
。
但是我们可以不创建一个新列“状态”,我们可以将值设置为“活动”或“非活动”,如结果屏幕截图中所述吗? @GMB
@SidduKattimani:我不建议存储这些派生信息。您可以使用查询即时计算它。或者,如果您将定期需要它,您可以创建一个视图。【参考方案2】:
如果您想同时使用这两个表,那么横向连接就可以满足您的需求:
select bds.date, bds.c_id, b.state, b.location
--CASE WHEN b.state = '%ActiveDecay%' between current_date- 10 and current_date THEN 'ActIve' ELSE 'DECAY' END as STATUS
FROM battery_date_series bds LEFT JOIN LATERAL
(SELECT b.*
FROM battery b
WHERE bds.c_id = b.c_id and b.date <= bds.date
ORDER BY b.date DESC
LIMIT 1
) b
ON 1=1
ORDER BY 1,2;
【讨论】:
我不想更新状态列,我想要一个名为“状态”的新列,如果我们在过去 5 中为快照表中的特定 c_id 输入了数据从当前日期开始的天数,则必须将其设置为“活动”,否则为“不活动”。不过,感谢您的回复:)以上是关于查找过去 X 天内的活跃客户的主要内容,如果未能解决你的问题,请参考以下文章
SQL Server:如何为同一张表中的不同客户获取 3 天内的滚动总和