计算每月新客户数

时间:2013-06-21 19:15:53

标签: sql sql-server sql-server-2008

出于某种原因,我对此感到困惑。

基本上,我正在寻找一个查询,可以找到自2010年以来每月新客户的数量。

我有客户的电子邮件地址(电子邮件),所有下订单(OrderID)以及它所在的日期(OrderDate)。该表是tblOrder。

我知道“新客户”是:(a)在日期/月之前从未订购的人和(b)在之后至少有一个订单的人日期/月

我希望输出最终是这样的,更简单的方法更好:

      01   02   03   04   05   06   07   08   09   10   11   12
2010  ##   ##   ##   ##   ##   ##   ##   ##   ##   ##   ##   ##
2011  ##   ##   ##   ##   ##   ##   ##   ##   ##   ##   ##   ##
2012  ##   ##   ##   ##   ##   ##   ##   ##   ##   ##   ##   ##

我得到了这个,但是伙计们,我认真的不是程序员,而且你们可能看起来很简单,但这些都是我的头脑而不是一直点击我。

SELECT <customer info> 
FROM <customer table> 
WHERE (SELECT COUNT(<order info>) 
    FROM <order table> 
    WHERE <customer info> = <current customer> 
        AND <date> < <target date>) = 0 
        AND (SELECT COUNT(<order info> 
            FROM <order table> 
            WHERE <customer info> = <current customer> 
            AND <date> > <target date>) > 0

我知道这也不是有效的SQL。所以我不知道该怎么做。而且我认为它只是提取了一个适用客户列表(意思是那些在输入的月份之前没有订购的客户),而不是将它们全部计算在内并总计它们,就像我最终想要的那样。

5 个答案:

答案 0 :(得分:2)

尝试:

select yr, [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12]
from
(select datepart(month,minDate) mth, datepart(year,minDate) yr, count(*) cnt
 from (select min(OrderDate) minDate, max(OrderDate) maxDate
       from tblOrder
       group by email) sq
 where datediff(month, minDate, maxDate) > 0
 group by datepart(month,minDate), datepart(year,minDate)) src
PIVOT
(max(cnt) 
 for mth in ([1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12]) ) pvt

SQLFiddle here

答案 1 :(得分:1)

首先定义新客户

select distinct FirstTimer.customer_id 
from
(select customer_id,min(order_date) as FirstOrderDate
from tblOrder 
group by customer_id
having Month(min(order_date))=month(TargetDate) and
       year(min(order_date))=year(targetDate)
) FirstTimer
join tblOrder ot on ot.customer_id=First_timer.customer_id
where ot.order_date > target_date

第一部分查找第一个订单在指定月份的所有客户。然后,您只需要那些满足第二个条件(在目标日期之后订购)的客户

没有表名和结构,无法创建整个查询,但希望上面的内容应该给你一点启动

答案 2 :(得分:0)

这将按年份和月份为您提供新的客户数量:

;WITH cteCustFirstMonth As
(   -- Gets the first order date for each active customer
    SELECT   email, 
             MIN(OrderDate)        as FirstOrderDate,
             YEAR(MIN(OrderDate))  as Yr,
             MONTH(MIN(OrderDate)) as Mnth
    FROM     tblOrder
    GROUP BY email
)
-- Groups the first order dates into Year and Month
SELECT   Yr,
         Mnth,
         COUNT(email) As cnt
FROM     cteFirstOrderDate
GROUP BY Yr, Mnth
ORDER BY Yr, Mnth

它不会以您请求的格式返回它们,但这可以在excel或SQL中完成,只需要额外的工作。

答案 3 :(得分:0)

轻微编辑@Mark Ba​​nnister的回答。 OP声明的目的是在他们下第一个订单的那个月捕获新客户的数量。 OP&#34;新客户&#34;的定义令人困惑的是,他指定:

  

a&#34;新客户&#34;是:(a)在此之前从未订购过的人   日期/月份和(b)在日期/月之后至少有一个的订单(强调添加)

也许这确实是OP想要的,但这更准确地被称为“新客户”,在接下来的一个月内成为重复购买者&#34;因为它消除了:

  1. 只下一个订单的客户
  2. 将所有订单放在同一日期/月份的客户
  3. @ Mark的正确解决方案(?)消除了这些客户,因为his SQL FIDDLE表明Fred @ home不算作新客户。

    然而,OP在其帖子的最后还说明了#34;适用的客户&#34;是:

      

    那些在输入的月份之前没有订购的人

    因此,为了捕获所有新客户(这是我认为OP真正追求的),我们仍然可以使用@Mark的优秀PIVOT解决方案,我们需要做的就是查看min(OrderDate)和只需忽略maxDate比较,如下所示:

    select yr, [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12]
    from
    (select datepart(month,minDate) mth, datepart(year,minDate) yr, count(*) cnt
     from (select min(OrderDate) minDate
           from tblOrder
           group by email) sq
     group by datepart(month,minDate), datepart(year,minDate)) src
    PIVOT
    (max(cnt) 
     for mth in ([1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12]) ) pvt
    

    通过汇总数据透视表中的所有计数(在Excel中快速简便)并与以下内容进行比较,可以快速检查以验证是否已捕获所有客户:

    SELECT COUNT(DISTINCT(email)) FROM tblOrder
    

答案 4 :(得分:-1)

SELECT EXTRACT(MONTH FROM orderdate) AS month,
       EXTRACT(YEAR FROM orderdate)  AS year, 
       COUNT(*) 
FROM (
       SELECT MIN(orderdate) AS orderdate, name
       FROM tblOrder
       GROUP BY name
     )
GROUP BY EXTRACT(MONTH FROM orderdate),
         EXTRACT(YEAR FROM orderdate)