我在SQL中处理以下问题(使用Vertica):
简而言之 - 为每个ID创建一个时间轴(在我有多行的表格中,我的示例中的订单,每个ID)
我想要实现的目标 - 我可以随时找到历史订单日期表,我想计算新客户(过去一个月的第一笔订单),活跃的客户 - (>过去1-3个月中的1个订单),被动客户 - (最近3-6个月没有订单)和非活动客户(无法订购> 6个月)费率。
到目前为止我采取了哪些步骤 - 我能够构建一个类似于下面示例的表格:
CustomerID Current order date Time between current/previous order First order date (all-time)
001 2015-04-30 12:06:58 (null) 2015-04-30 12:06:58
001 2015-09-24 17:30:59 147 05:24:01 2015-04-30 12:06:58
001 2016-02-11 13:21:10 139 19:50:11 2015-04-30 12:06:58
002 2015-10-21 10:38:29 (null) 2015-10-21 10:38:29
003 2015-05-22 12:13:01 (null) 2015-05-22 12:13:01
003 2015-07-09 01:04:51 47 12:51:50 2015-05-22 12:13:01
003 2015-10-23 00:23:48 105 23:18:57 2015-05-22 12:13:01
一点直觉:客户001下了三个订单,第二个订单是第一个订单后147天。客户002总共只下了一个订单。
我认为接下来的步骤应该 - 我想知道每个日期(也就是某个用户没有下订单的日期),每个CustomerID,多长时间从他/她的最后一次订单开始。这意味着我会为每个CustomerID创建某种时间轴。在上面给出的示例中,我将获得287(2015年5月1日至2016年2月11日之间的天数,此表的时间跨度)每个CustomerID的行数。 我难以解决上一步。当我执行此步骤时,我想创建一个字段,在每个日期显示最后一个订单日期,最后一个订单日期和当前日期之间的时间段,以及在当前日期有人处于什么状态。对于前面介绍的示例,这看起来像这样:
CustomerID Last order date Current date Time between current date /last order State
001 2015-04-30 12:06:58 2015-05-01 00:00:00 0 00:00:00 New
...
001 2015-04-30 12:06:58 2015-06-30 00:00:00 60 11:53:02 Active
...
001 2015-09-24 17:30:59 2016-02-01 00:00:00 129 11:53:02 Passive
...
...
002 2015-10-21 17:30:59 2015-10-22 00:00:00 0 06:29:01 New
...
002 2015-10-21 17:30:59 2015-11-30 00:00:00 39 06:29:01 Active
...
...
003 2015-05-22 12:13:01 2015-06-23 00:00:00 31 11:46:59 Active
...
003 2015-07-09 01:04:51 2015-10-22 00:00:00 105 11:46:59 Inactive
...
在点上应该有所有的中间日期但是为了空间我把这些留在了桌子之外。
当我知道每个日期每个客户的状态(主动/被动/非活动)时,我的计划是按日期对状态和组进行求和,这应该给出新客户,主动客户,被动客户和非活动客户的总和。从这里开始,我可以轻松计算每个日期的费率。
任何知道我如何才能完成这项任务的人?
注意 - 如果有人有其他想法如何实现上述目标(使用其他方法与我想到的方法相比),请告诉我!
答案 0 :(得分:1)
修改强>
假设您从这样的表开始:
SQL> select * from ord order by custid, ord_date ;
custid | ord_date
--------+---------------------
1 | 2015-04-30 12:06:58
1 | 2015-09-24 17:30:59
1 | 2016-02-11 13:21:10
2 | 2015-10-21 10:38:29
3 | 2015-05-22 12:13:01
3 | 2015-07-09 01:04:51
3 | 2015-10-23 00:23:48
(7 rows)
您可以使用Vertica的时间序列分析函数TS_FIRST_VALUE(),TS_LAST_VALUE()填充空白并将last_order日期插入当前日期:
然后你只需加入一个从同一个表生成的Vertica的TimeSeries,从每个客户放置他/她的第一个订单到现在(current_date)的第一天开始的间隔一天:
select
custid,
status_dt,
last_order_dt,
case
when status_dt::date - last_order_dt::date < 30 then case
when nord = 1 then 'New' else 'Active' end
when status_dt::date - last_order_dt::date < 90 then 'Active'
when status_dt::date - last_order_dt::date < 180 then 'Passive'
else 'Inactive'
end as status
from (
select
custid,
last_order_dt,
status_dt,
conditional_true_event (first_order_dt is null or
last_order_dt > lag(last_order_dt))
over(partition by custid order by status_dt) as nord
from (
select
custid,
ts_first_value(ord_date) as first_order_dt ,
ts_last_value(ord_date) as last_order_dt ,
dt::date as status_dt
from
( select custid, ord_date from ord
union all
select distinct(custid) as custid, current_date + 1 as ord_date from ord
) z timeseries dt as '1 day' over (partition by custid order by ord_date)
) x
) y
where status_dt <= current_date
order by 1, 2
;
你会得到这样的东西:
custid | status_dt | last_order_dt | status
--------+------------+---------------------+---------
1 | 2015-04-30 | 2015-04-30 12:06:58 | New
1 | 2015-05-01 | 2015-04-30 12:06:58 | New
1 | 2015-05-02 | 2015-04-30 12:06:58 | New
...
1 | 2015-05-29 | 2015-04-30 12:06:58 | New
1 | 2015-05-30 | 2015-04-30 12:06:58 | Active
1 | 2015-05-31 | 2015-04-30 12:06:58 | Active
...
etc.