Sql-用于计算每月买家数量的查询
我真的需要您的帮助来创建一个查询,在这里我可以显示2017年1月至2017年12月期间一个月内订购超过1份订单的买家数量 此外,在未来12个月内没有再次订购的买家数量 下面是我的数据样本 日期 CID客户id 订单号 2017-02-03 0:23 924832 000023149 2017-02-05 0:11 924162 000092384 2017-07-01 0:53 914861 000023182 2017-08-09 0:42 924832 000021219Sql-用于计算每月买家数量的查询,sql,sql-server,Sql,Sql Server,我真的需要您的帮助来创建一个查询,在这里我可以显示2017年1月至2017年12月期间一个月内订购超过1份订单的买家数量 此外,在未来12个月内没有再次订购的买家数量 下面是我的数据样本 日期 CID客户id 订单号 2017-02-03 0:23 924832 000023149 2017-02-05 0:11 924162 000092384 2017-07-01 0:53 914861 000023182 2017-08-09 0:42 924832 000021219 如果我理解正确的话
如果我理解正确的话,带有示例数据的表就是订单表,这意味着一行就是一个订单,具有唯一的OrderNo 如果是这样,则必须使用以下查询:
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:我刚刚注意到你的评论,澄清了在未来1200万年内没有订购的买家的含义:如果你在2017年1月订购,那么从2017年2月到2018年2月,你不应该有任何订单
对于这种情况,查询的部分
datediff(MONTH, c.[Date], LEAD(c.[Date]) over (partition by c.[CID] order by c.[Date])) > 12
应改为
DATEADD(DAY,1,EOMONTH(DATEADD(MONTH,13,C.[DATE]))) <= LEAD(c.[Date]) over (partition by c.[CID] order by c.[Date])
我在这里设置的
这应该与您的描述相匹配:
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
我不明白。如何确定第一列?结果与样本数据有什么关系?应该是每月一次,比如2017-01-01年1月,2017-02-01年2月,等等。对于没有在第一列订购下一个1200万格式的买家来说,这意味着“yyyy-mm-dd hh:mm”。不确定这是否是您所指的。@Mr.Bhosale这就像是在接下来的12个月内没有再次订购的买家数量,就像如果您在2017年1月订购,您在2017年2月至2018年2月期间不应该有任何订单。
;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)
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