[英]Sql - Query to calculate no. of buyers monthly
i would really need your help in creating a query where i can show the number of buyers who made more than 1 order in a month for the period January 2017 to December 2017.我真的需要你的帮助来创建一个查询,我可以在其中显示 2017 年 1 月至 2017 年 12 月期间一个月内订购超过 1 个订单的买家数量。
Also, the no.此外,没有。 of these buyers that didn't order again within the next 12 months.这些买家中没有在接下来的 12 个月内再次订购。
Below is sample my data.以下是我的数据示例。
Date日期 | CID (customer id) CID(客户 ID) | OrderNo订单号 |
---|---|---|
2017-02-03 0:23 2017-02-03 0:23 | 924832 924832 | 000023149 000023149 |
2017-02-05 0:11 2017-02-05 0:11 | 924162 924162 | 000092384 000092384 |
2017-07-01 0:53 2017-07-01 0:53 | 914861 914861 | 000023182 000023182 |
2017-08-09 0:42 2017-08-09 0:42 | 924832 924832 | 000021219 000021219 |
Output should be like this Output 应该是这样的
Month月 | Buyers with >1 order > 1个订单的买家 | Buyers that didnt order for the next 12M未订购下一个 12M 的买家 |
---|---|---|
2017-01-01 2017-01-01 | 122 122 | 92 92 |
2017-02-01 2017-02-01 | 74 74 | 24 24 |
2017-03-01 2017-03-01 | 216 216 | 107 107 |
This should to match your description:这应该与您的描述相匹配:
with cte as
(
select
ca.ym
,cid
-- flag buyers who made more than 1 order in a month
,case when count(*) > 1 then 1 else 0 end as multi_buy
-- flag buyers that didn't order again within the next 12 months
,case when LEAD(ym,1,ym) -- month of next order
over (partition by CID
order by ym) < DATEADD(month, 13, ym)
then 0
else 1
end as no_buy_within_range
from orders
CROSS APPLY
( -- truncate the OrderDate to the 1st of month
SELECT convert(Date, DATEADD(month, DATEDIFF(month, 0, OrderDate), 0)) as ym
) as ca
group by
ym
,cid
)
select
ym
,sum(multi_buy)
,sum(no_buy_within_range)
from cte
group by ym
order by ym
If I understood correctly, the table with sample data is the table of Orders , which means that one row is one order with unique OrderNo.如果我理解正确的话,带有示例数据的表是Orders表,这意味着一行是一个具有唯一 OrderNo 的订单。
If so, then the following query would have to work:如果是这样,那么以下查询将必须工作:
SELECT d.[MONTH], COUNT(distinct d.[Buyers with >1 order]) [Buyers with >1 order],
COUNT(distinct d.[Buyers that didnt order for the next 12M]) [Buyers that didnt order for the next 12M]
FROM
(
select c.[MONTH], c.[Date], c.CID, c.OrderNo,
c.[Buyers with >1 order],
case when c.[Buyers with >1 order] is not null and
datediff(MONTH, c.[Date], LEAD(c.[Date]) over (partition by c.[CID] order by c.[Date])) > 12
THEN C.CID END [Buyers that didnt order for the next 12M]
from (
SELECT b.[MONTH], b.[Date], b.CID, b.OrderNo,
case when COUNT(*) over (partition by b.[MONTH], b.CID) > 1 then b.CID end [Buyers with >1 order]
FROM (
SELECT convert(date, DATEADD(month, DATEDIFF(month, 0, a.Date), 0)) [MONTH],
A.[Date], A.CID, A.OrderNo
FROM Orders a
) b
) c
) d
WHERE D.[MONTH] BETWEEN '2017-01-01' AND '2017-12-01'
GROUP BY d.[MONTH]
UPD: I just noted your comment clarifying the meaning of "Buyers that didn't order for the next 12M": "if you ordered last January 2017, you shouldnt have any orders from Feb 2017 to Feb 2018" UPD:我刚刚注意到您的评论澄清了“没有为下一个 12M 订购的买家”的含义:“如果您在 2017 年 1 月订购,则从 2017 年 2 月到 2018 年 2 月您不应该有任何订单”
For such cases, the part of the query对于这种情况,查询的部分
datediff(MONTH, c.[Date], LEAD(c.[Date]) over (partition by c.[CID] order by c.[Date])) > 12
ought to be altered to应该改成
DATEADD(DAY,1,EOMONTH(DATEADD(MONTH,13,C.[DATE]))) <= LEAD(c.[Date]) over (partition by c.[CID] order by c.[Date])
Then the full query would look like:然后完整的查询将如下所示:
SELECT d.[MONTH], COUNT(distinct d.[Buyers with >1 order]) [Buyers with >1 order],
COUNT(distinct d.[Buyers that didnt order for the next 12M]) [Buyers that didnt order for the next 12M]
FROM
(
select c.[MONTH], c.[Date], c.CID, c.OrderNo,
c.[Buyers with >1 order],
case when c.[Buyers with >1 order] is not null and
datediff(MONTH, c.[Date], LEAD(c.[Date]) over (partition by c.[CID] order by c.[Date])) > 12
THEN C.CID END [Buyers that didnt order for the next 12M]
from (
SELECT b.[MONTH], b.[Date], b.CID, b.OrderNo,
case when COUNT(*) over (partition by b.[MONTH], b.CID) > 1 then b.CID end [Buyers with >1 order]
FROM (
SELECT convert(date, DATEADD(month, DATEDIFF(month, 0, a.Date), 0)) [MONTH],
A.[Date], A.CID, A.OrderNo
FROM Orders a
) b
) c
) d
WHERE D.[MONTH] BETWEEN '2017-01-01' AND '2017-12-01'
GROUP BY d.[MONTH]
I made this setup here http://sqlfiddle.com/#!18/090ac/5我在这里做了这个设置http://sqlfiddle.com/#!18/090ac/5
;WITH CTE AS
(
select CAST(DATEADD(month, DATEDIFF(month, 0, OrderDate), 0) as DATE) AS OrderMonth,
CID,count(OrderNo) as OrderCount
from Orders
group by CAST(DATEADD(month, DATEDIFF(month, 0, OrderDate), 0) as DATE), CID
)
select q1.OrderMonth, q1.[MultipleOrderBuyers], q2.OrderedOverNext12Mo
from
(
select OrderMonth,
SUM(CASE WHEN OrderCount > 1 THEN 1 ELSE 0 END) as [MultipleOrderBuyers]
from CTE
group by OrderMonth
)q1
LEFT OUTER JOIN
(
select OrderMonth, SUM(OrderedOverNext12Mo) as OrderedOverNext12Mo
from
(
select OrderMonth, CID,
( select CASE WHEN SUM(OrderCount) > 1 THEN 1 ELSE 0 END
from CTE
where OrderMonth BETWEEN DATEADD(month,1,c1.OrderMonth) AND DATEADD(month,13,c1.OrderMonth)
) as OrderedOverNext12Mo
from CTE c1
group by OrderMonth, CID
)c
group by OrderMonth
)q2 on (q1.OrderMonth = q2.OrderMonth)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.