我有一个电子商务网站的order_list表,我需要从该表创建一个月内购买了多少客户的报告。在这些客户中,有多少是首次客户,在最近90天内有多少人下了订单,在最近180天内有多少人,等等。
完成的报告将是一个如下所示的excel网格:
这是我现在拥有的查询:
SELECT months.month,
count(distinct(case when months.month = Trunc (orders.order_date, 'MONTH') then orders.email_address else null end)) as total_monthly_orders,
count(distinct(case when months.month = Trunc (orders.order_date, 'MONTH') and order_rank = 1 then orders.email_address else null end)) as monthly_first_purchasers,
/* This is the logic thats not working right now*/
/*count(distinct(case when (months.month - (Trunc (orders.order_date, 'MONTH'))) <= 92 then orders.email_address else null end)) as less_than_3_month_purchasers,
count(distinct(case when (months.month - (Trunc (orders.order_date, 'MONTH'))) <= 181 then orders.email_address else null end)) as less_than_6_month_purchasers,
count(distinct(case when (months.month - (Trunc (orders.order_date, 'MONTH'))) <= 273 then orders.email_address else null end)) as less_than_9_month_purchasers,
count(distinct(case when (months.month - (Trunc (orders.order_date, 'MONTH'))) <= 365 then orders.email_address else null end)) as less_than_12_month_purchasers,
count(distinct(case when (months.month - (Trunc (orders.order_date, 'MONTH'))) > 365 then orders.email_address else null end)) as one_year_plus_purchasers*/
FROM ( SELECT Trunc (TO_DATE (A.create_date), 'MONTH') AS month
FROM ORDER_DETAIL A
WHERE TO_DATE (A.create_date) >= '1-Jan-2018'
GROUP BY Trunc (TO_DATE (A.create_date), 'MONTH')
ORDER BY Trunc (TO_DATE (A.create_date), 'MONTH') ASC) months
INNER JOIN (SELECT A.EMAIL_ADDRESS,
A.DEMANDWARE_ORDER_NUMBER AS order_id,
TO_DATE (A.CREATE_DATE) AS order_date,
RANK ()
OVER (PARTITION BY A.EMAIL_ADDRESS
ORDER BY A.DEMANDWARE_ORDER_NUMBER ASC)
AS Order_rank
FROM ORDER_DETAIL A
WHERE A.email_address IS NOT NULL) orders
ON months.month >= Trunc (orders.order_date, 'MONTH')
Group by months.month
Order by months.month ASC
我测试了该查询,并正确地提取了总客户和首次使用的客户。但是我不知道该如何吸引最近一次购买是在过去3个月/ 6个月等之内的客户。
有人可以帮我吗?
我已经对其他查询进行了检查,“客户总数”和“首次客户”列中的值正确。但是其他列中的值不正确。本质上,要对此进行测试,每个存储桶中的客户总数应等于总客户数。
例如:如果1月份我们总共有34,016个客户,则<3个月存储桶中没有166,148个客户
答案 0 :(得分:0)
如果我的理解正确,那么您的CASE WHEN
需要检查月份号而不是日期号。
(months.month - (Trunc (orders.order_date, 'MONTH'))) <= 3
代替
(months.month - (Trunc (orders.order_date, 'MONTH'))) <= 92
然后,您需要在month
子查询中添加查询列,以进行一年以上的判断。
使用EXTRACT
列中的order_date
。
(EXTRACT(year FROM months.order_date) - EXTRACT(year FROM orders.order_date)) > 0
查询可能是这样的。
SELECT months.month,
count(distinct(case when months.month = Trunc (orders.order_date, 'MONTH') then orders.email_address else null end)) as total_monthly_orders,
count(distinct(case when months.month = Trunc (orders.order_date, 'MONTH') and order_rank = 1 then orders.email_address else null end)) as monthly_first_purchasers,
count(distinct(case when (months.month - (Trunc (orders.order_date, 'MONTH'))) <= 3 then orders.email_address else null end)) as less_than_3_month_purchasers,
count(distinct(case when (months.month - (Trunc (orders.order_date, 'MONTH'))) <= 6 then orders.email_address else null end)) as less_than_6_month_purchasers,
count(distinct(case when (months.month - (Trunc (orders.order_date, 'MONTH'))) <= 9 then orders.email_address else null end)) as less_than_9_month_purchasers,
count(distinct(case when (months.month - (Trunc (orders.order_date, 'MONTH'))) <= 12 then orders.email_address else null end)) as less_than_12_month_purchasers,
count(distinct(case when (EXTRACT(year FROM months.order_date) - EXTRACT(year FROM orders.order_date)) > 0 then orders.email_address else null end)) as one_year_plus_purchasers
FROM ( SELECT Trunc (TO_DATE (A.create_date), 'MONTH') AS month,
TO_DATE (A.CREATE_DATE) order_date
FROM ORDER_DETAIL A
WHERE TO_DATE (A.create_date) >= '1-Jan-2018'
GROUP BY Trunc (TO_DATE (A.create_date), 'MONTH')
ORDER BY Trunc (TO_DATE (A.create_date), 'MONTH') ASC) months
INNER JOIN (SELECT A.EMAIL_ADDRESS,
A.DEMANDWARE_ORDER_NUMBER AS order_id,
TO_DATE (A.CREATE_DATE) AS order_date,
RANK () OVER (PARTITION BY A.EMAIL_ADDRESS ORDER BY A.DEMANDWARE_ORDER_NUMBER ASC) AS Order_rank
FROM ORDER_DETAIL A
WHERE A.email_address IS NOT NULL
) orders
ON months.month >= Trunc (orders.order_date, 'MONTH')
Group by months.month
Order by months.month ASC
答案 1 :(得分:0)
如果我没看错,这可能会给你要点。创建一个二进制标志,以判断最后一个订单是否在最近几个月之内。
如果订单日期跨度多年,这将无法真正起作用,因此一旦您到2019年就会中断。但这很容易解决。我真的无法说出您要如何处理多年。
SELECT order_month,
SUM(first_order) AS customerWithFirstOrder,
SUM(within_three_months) AS customersWithinThreeMonths,
SUM(within_six_months) AS customersWithinSixMonths
FROM (SELECT DISTINCT
customer,
case when prev_order_date IS NULL THEN 1
ELSE 0
END first_order,
case when prev_order_date >= DATE_ADD(month,order_month,-3) IS NULL
THEN 1 ELSE 0
END within_three_months,
case when prev_order_date >= DATE_ADD(month,order_month,-6) IS NULL
THEN 1
ELSE 0
END within_six_months,
TRUNC(order_date, 'MONTH') order_month
FROM (SELECT LAG(TO_DATE(create_date)) OVER
( PARTITION BY customer
ORDER BY TO_DATE(create_date)
) AS prev_order_date,
customer,
TO_DATE(create_date) order_Date
FROM ORDER_DETAIL
WHERE TO_DATE (A.create_date) >= '1-Jan-2018'
) TMP
);
答案 2 :(得分:0)
我根据用户用例创建了一个虚拟表,并根据您的要求编写了查询。查询非常简单。无需加入表2次。 下面是我的代码。
-表格创建
create table ORDER_DETAIL
(
create_date date, -- date on which customer created account.
EMAIL_ADDRESS varchar2(100),
DEMANDWARE_ORDER_NUMBER number, -- orderid
order_date date
);
-插入数据
insert into ORDER_DETAIL values (to_date('1-JAN-2018'),'xyz@gmail.com',1,sysdate);
insert into ORDER_DETAIL values (to_date('31-JAN-2018'),'xyz@gmail.com',4,sysdate);
insert into ORDER_DETAIL values (to_date('3-MAR-2018'),'xyz@gmail.com',2,sysdate-8);
-查询
select
count(*) as count_per_month,
to_char(CREATE_DATE,'MON') as customer_perchase_month,
sum((case
when to_char(CREATE_DATE,'MON') = to_char(ORDER_DATE,'MON')
then
1
else
0
end ))First_Time_Customer,
sum((case
when months_between(trunc(ORDER_DATE) , trunc(CREATE_DATE)) < 3 then
1
else
0
end )) less_than_3_months,
sum((case
when months_between((trunc(ORDER_DATE)) , trunc(CREATE_DATE)) between 3 and 6 then
1
else
0
end )) less_than_6_months ,
sum((case
when months_between((trunc(ORDER_DATE)) , trunc(CREATE_DATE)) between 6 and 12 then
1
else
0
end )) less_than_12_months,
sum((case
when months_between(trunc(ORDER_DATE) , trunc(CREATE_DATE)) > 12 then
1
else
0
end )) greater_than_12
from
ORDER_DETAIL od
WHERE TO_DATE (create_date) >= '1-Jan-2018'
and EMAIL_ADDRESS is not null
group by to_char(CREATE_DATE,'MON');
希望这可以解决您的要求。
关于Ankit。