对于队列分析的需要,我试图让每个客户的下一步行动(取消订阅,升级,降级......)
我有一个包含以下数据的快照:
customer | month | last_action | last_action_date
1 01-01-2012 subscription 01-01-2012
1 02-01-2012 subscription 01-01-2012
1 03-01-2012 subscription 01-01-2012
1 04-01-2012 downgrade 04-01-2012
1 05-01-2012 downgrade 04-01-2012
1 06-01-2012 downgrade 04-01-2012
1 07-01-2012 unsubscription 07-01-2012
正如您所看到的,该行动仅在完成月份时才知道,在01-01-2012月我们还不知道客户在04-01-2012期间降级,因此我们无法分析他的使用行为相对于他的降级月份。取消订阅也是一样。
所需的数据集如下:
customer | month | downgrade_date | unsubscription_date
1 01-01-2012 04-01-2012 07-01-2012
1 02-01-2012 04-01-2012 07-01-2012
1 03-01-2012 04-01-2012 07-01-2012
1 04-01-2012 12-31-9999 07-01-2012
1 05-01-2012 12-31-9999 07-01-2012
1 06-01-2012 12-31-9999 07-01-2012
1 07-01-2012 12-31-9999 07-01-2012
我可以轻松地使用last_value分析函数取消订阅日期,但没有找到获得降级日期的方法。
这是我的SQL查询:
SELECT month_id,
customer_id,
CASE
WHEN LAST_VALUE(last_action) OVER (PARTITION BY customer_id ORDER BY month_id RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) = 'unsubscription' THEN LAST_VALUE(last_action_date) OVER (PARTITION BY customer_id ORDER BY month_id RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
ELSE TO_DATE('99991231', 'yyyymmdd')
END unsubscription_date
FROM my_table
;
任何获取“下一个”操作日期的方法,例如“downgrade_date”。
我正在使用Oracle。
答案 0 :(得分:1)
在oracle 11中,您可以使用lead()
和ignore nulls
选项执行此操作:
select customer, MONTH,
lead(case when last_action = 'downgrade' then last_action_date end ignore nulls) over
(partition by customer order by month desc) as downgrade_date,
lead(case when last_action = 'unsubscription' then last_action_date end ignore nulls) over
(partition by customer order by month desc) as downgrade_date,
from my_table t
如果您没有ignore nulls
,则可以使用min()
执行类似操作:
select customer, MONTH,
min(case when last_action = 'downgrade' then last_action_date end) over
(partition by customer order by month range between current and unbounded following
) as downgrade_date,
min(case when last_action = 'unsubscription' then last_action_date end) over
(partition by customer order by month range between current and unbounded following
) as unsubscription_date
from my_table t