用于计算不同客户状态的滚动 Windows 函数
Rolling Windows function for count distinct customer state
我正在尝试计算过去 3 个月、6 个月内不同的客户状态。
我有 customer_id
、customer_status
(活跃与否)和 calendar_date
。因此,每个客户都可以随着时间的推移多次出现,因为它可以在不同的时间活跃或不活跃。
但是当我尝试下面的代码时它不起作用,因为 windows 函数
不支持 count(distinct)
select *,
count(distinct customer_status)
over(partition by customer_id
order by date_trunc ('month',calendar_date) rows between 2 PRECEDING and current row)
from customer_details
我可以在同一个月获得不同的状态[见下文]但我想为 count(distinct) 3 个月和 6 个月创建两个字段。
select calendar_date,
date_trunc ('month',calendar_date) as calendar_month,
customer_id,
customer_status,
count(distinct customer_status)
over(partition by customer_id, calendar_month))
from customer_details
order by calendar_date
有人可以支持我吗?
最后的 select 应该有以下列:
calendar_date [already exist]
calendar_month [already exist]
customer_status [already exist]
count_distinct_status_3month [new]
count_distinct_status_6months [new]
我想使用 windows 函数
这没有直接的功能,而是需要使用自连接。例如,在您的情况下,查询将是这样的。
select cust.calendar_date, date_trunc('month', cust.calendar_date) as calendar_month,
cust.customer_id, count(distinct cust_3mon.customer_status) as count_distinct_status_3month,
count(distinct cust_6mon.customer_status) as count_distinct_status_6month
from customer_details as cust
left join customer_details as cust_3mon
on cust.customer_id=cust_3mon.customer_id
and (date_trunc('month', cust.calendar_date)-date_trunc('month', cust_3mon.calendar_date)) between interval '0 months' and interval '3 months'
left join customer_details as cust_6mon
on cust.customer_id=cust_6mon.customer_id
and (date_trunc('month', cust.calendar_date)-date_trunc('month', cust_6mon.calendar_date)) between interval '0 months' and interval '6 months'
group by 1,2,3
order by 3,2
sqlfiddle link here
我不认为你可以用 window 函数来做到这一点。您可以使用横向连接来做到这一点:
select cd.*, cd2.*
from customer_details cd cross join lateral
(select count(distinct cd2.customer_status) as cnt1,
count(distinct case when cd2.calendar_date > cd.calendar_date - interval '3 month' then cd2.customer_status end) as cnt2,
count(distinct case when cd2.calendar_date > cd.calendar_date - interval '6 month' then cd2.customer_status end) as cnt3
from customer_details cd2
where cd2.customer_id = cd.customer_id
) cd2
我正在尝试计算过去 3 个月、6 个月内不同的客户状态。
我有 customer_id
、customer_status
(活跃与否)和 calendar_date
。因此,每个客户都可以随着时间的推移多次出现,因为它可以在不同的时间活跃或不活跃。
但是当我尝试下面的代码时它不起作用,因为 windows 函数
不支持 count(distinct)select *,
count(distinct customer_status)
over(partition by customer_id
order by date_trunc ('month',calendar_date) rows between 2 PRECEDING and current row)
from customer_details
我可以在同一个月获得不同的状态[见下文]但我想为 count(distinct) 3 个月和 6 个月创建两个字段。
select calendar_date,
date_trunc ('month',calendar_date) as calendar_month,
customer_id,
customer_status,
count(distinct customer_status)
over(partition by customer_id, calendar_month))
from customer_details
order by calendar_date
有人可以支持我吗?
最后的 select 应该有以下列:
calendar_date [already exist]
calendar_month [already exist]
customer_status [already exist]
count_distinct_status_3month [new]
count_distinct_status_6months [new]
我想使用 windows 函数
这没有直接的功能,而是需要使用自连接。例如,在您的情况下,查询将是这样的。
select cust.calendar_date, date_trunc('month', cust.calendar_date) as calendar_month,
cust.customer_id, count(distinct cust_3mon.customer_status) as count_distinct_status_3month,
count(distinct cust_6mon.customer_status) as count_distinct_status_6month
from customer_details as cust
left join customer_details as cust_3mon
on cust.customer_id=cust_3mon.customer_id
and (date_trunc('month', cust.calendar_date)-date_trunc('month', cust_3mon.calendar_date)) between interval '0 months' and interval '3 months'
left join customer_details as cust_6mon
on cust.customer_id=cust_6mon.customer_id
and (date_trunc('month', cust.calendar_date)-date_trunc('month', cust_6mon.calendar_date)) between interval '0 months' and interval '6 months'
group by 1,2,3
order by 3,2
sqlfiddle link here
我不认为你可以用 window 函数来做到这一点。您可以使用横向连接来做到这一点:
select cd.*, cd2.*
from customer_details cd cross join lateral
(select count(distinct cd2.customer_status) as cnt1,
count(distinct case when cd2.calendar_date > cd.calendar_date - interval '3 month' then cd2.customer_status end) as cnt2,
count(distinct case when cd2.calendar_date > cd.calendar_date - interval '6 month' then cd2.customer_status end) as cnt3
from customer_details cd2
where cd2.customer_id = cd.customer_id
) cd2