每年重复客户(保留)

时间:2013-06-28 15:30:45

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

我一直在努力,我不认为我做得对。 | d

我们的数据库没有跟踪我们保留的客户数量,因此我们寻找替代方法。概述了in this article。它建议您填写此表:

Year  Number of Customers   Number of customers Retained in 2009    Percent (%) Retained in 2009    Number of customers Retained in 2010    Percent (%) Retained in 2010  ....

2008
2009
2010
2011
2012
Total

该表将在标题中显示2012年。我只是在节省空间。

它告诉您找到您在起始年度中拥有的客户总数。为此,我使用此查询,因为我们的开始年份是2008年:

select YEAR(OrderDate) as 'Year', COUNT(distinct(billemail)) as Customers
from dbo.tblOrder
where OrderDate >= '2008-01-01' and OrderDate <= '2008-12-31'
group by YEAR(OrderDate)

目前我们只是通过电子邮件地址区分客户。

然后,您必须搜索在以后几年再次购买的同名客户(我们的是2009年,10年,11年和12年)。

我想出了这个。它应该找到在2008年和2009年都购买的人。

SELECT YEAR(OrderDate) as 'Year',COUNT(distinct(billemail)) as Customers
FROM dbo.tblOrder o with (nolock)
WHERE o.BillEmail IN (SELECT DISTINCT o1.BillEmail 
        FROM dbo.tblOrder o1 with (nolock)
        WHERE o1.OrderDate BETWEEN '2008-1-1' AND '2009-1-1')
    AND o.BillEmail IN (SELECT DISTINCT o2.BillEmail 
        FROM dbo.tblOrder o2 with (nolock)
        WHERE o2.OrderDate BETWEEN '2009-1-1' AND '2010-1-1')
    --AND o.OrderDate BETWEEN '2008-1-1' AND '2013-1-1' 
    AND o.BillEmail NOT LIKE '%@halloweencostumes.com'
    AND o.BillEmail NOT LIKE ''
GROUP BY YEAR(OrderDate)

所以我只是找到那些年份购买的客户。然后我正在做一个独立的查询,找到那些在2008年和2010年,然后是08年和11年,然后是08年和12年购买的人。这一个找到2008年和2010年的购买者:

SELECT YEAR(OrderDate) as 'Year',COUNT(distinct(billemail)) as Customers
FROM dbo.tblOrder o with (nolock)
WHERE o.BillEmail IN (SELECT DISTINCT o1.BillEmail 
        FROM dbo.tblOrder o1 with (nolock)
        WHERE o1.OrderDate BETWEEN '2008-1-1' AND '2009-1-1')
    AND o.BillEmail IN (SELECT DISTINCT o2.BillEmail 
        FROM dbo.tblOrder o2 with (nolock)
        WHERE o2.OrderDate BETWEEN '2010-1-1' AND '2011-1-1')
    --AND o.OrderDate BETWEEN '2008-1-1' AND '2013-1-1' 
    AND o.BillEmail NOT LIKE '%@halloweencostumes.com'
    AND o.BillEmail NOT LIKE ''
GROUP BY YEAR(OrderDate)

所以你看我对每年的比较都有不同的查询。他们都是无关的。所以最后我只是找到了2008年和2009年购买的人,然后是2008年和2010年购买的可能不同的团体,依此类推。为了准确起见,我每次都必须使用相同的2008年买家分组吗?那么他们在2009年,2010年和2011年以及2012年购买了什么?

这是我担心的地方,不知道如何继续甚至找到这样的数据。

任何建议将不胜感激!谢谢!

2 个答案:

答案 0 :(得分:1)

基于每个客户的交叉表如何帮助您...

通过比较客户,您可以开始分析更多 当前年度,每个年份的客户总数。 从那里你可以在你的最终输出中运行你想要的任何百分比

这应该可以帮助您了解所有相关年份的所有年份,并且您可以根据需要不断添加年份进行比较。它应该非常快,特别是如果你有一个索引(BillEMail,OrderDate)。

前提是内部查询只是吹过所有记录,如果在给定年份内有任何订单(通过MAX()),则在客户的基础上设置1的标志。它是通过case / when来检测客户的每一年。一旦确定了,那么外部查询会比较每个客户,如果他们在一年内与之前的销售比较,那么,SUM()1对0,你有保留计数。

SELECT
      SUM( case when PreQry.C2011 = 1 and PreQry.C2012 = 1 then 1 else 0 end ) as Retain2011_2012,
      SUM( case when PreQry.C2010 = 1 and PreQry.C2011 = 1 then 1 else 0 end ) as Retain2010_2011,
      SUM( case when PreQry.C2009 = 1 and PreQry.C2010 = 1 then 1 else 0 end ) as Retain2009_2010,
      SUM( case when PreQry.C2008 = 1 and PreQry.C2009 = 1 then 1 else 0 end ) as Retain2008_2009,
      SUM( PreQry.C2012 ) CustCount2012,
      SUM( PreQry.C2011 ) CustCount2011,
      SUM( PreQry.C2010 ) CustCount2010,
      SUM( PreQry.C2009 ) CustCount2009,
      SUM( PreQry.C2008 ) CustCount2008
   from 
      ( select 
              O.BillEMail as customer,
              MAX( CASE when YEAR( O.OrderDate ) = 2012 then 1 else 0 end ) as C2012, 
              MAX( CASE when YEAR( O.OrderDate ) = 2011 then 1 else 0 end ) as C2011, 
              MAX( CASE when YEAR( O.OrderDate ) = 2010 then 1 else 0 end ) as C2010, 
              MAX( CASE when YEAR( O.OrderDate ) = 2009 then 1 else 0 end ) as C2009, 
              MAX( CASE when YEAR( O.OrderDate ) = 2008 then 1 else 0 end ) as C2008
           from 
              dbo.tblOrder O
           where 
                  O.OrderDate >= '2008-01-01' 
              AND O.BillEmail NOT LIKE '%@halloweencostumes.com'
              AND O.BillEmail NOT LIKE ''
           group by 
              O.BillEMail ) as PreQry

现在,如果您想要检测给定年份的“新”数量,您可以添加其他列,例如测试上一年销售标志= 0与当前年份= 1,例如

SUM( case when PreQry.C2011 = 0 and PreQry.C2012 = 1 then 1 else 0 end ) as NewIn2012,
SUM( case when PreQry.C2010 = 0 and PreQry.C2011 = 1 then 1 else 0 end ) as NewIn2011,
SUM( case when PreQry.C2009 = 0 and PreQry.C2010 = 1 then 1 else 0 end ) as NewIn2010,
SUM( case when PreQry.C2008 = 0 and PreQry.C2009 = 1 then 1 else 0 end ) as NewIn2009

答案 1 :(得分:0)

如果我理解你的问题是对的,那么你听起来好像已经混淆了细节。这取决于您希望定义“保留”的内容。怎么样'还买了一些前一年'?然后,对于第X年,如果客户在前一年也向您购买,则会保留该客户。

2012年,例如:

SELECT YEAR(OrderDate) as 'Year',COUNT(distinct(billemail)) as Customers
FROM dbo.tblOrder o with (nolock)
WHERE o.BillEmail IN (SELECT DISTINCT o1.BillEmail 
        FROM dbo.tblOrder o1 with (nolock)
        WHERE o1.OrderDate BETWEEN '2012-1-1' AND '2013-1-1')
    AND o.BillEmail IN (SELECT DISTINCT o2.BillEmail 
        FROM dbo.tblOrder o2 with (nolock)
        WHERE o2.OrderDate < '2012-1-1')
    AND o.BillEmail NOT LIKE '%@halloweencostumes.com'
    AND o.BillEmail NOT LIKE ''
GROUP BY YEAR(OrderDate)

这有用吗?

修改

你可以更进一步,抽象出年份,所以1个查询就足够了:

SELECT YEAR(O.OrderDate) as 'Year',COUNT(distinct(billemail)) as Customers
FROM dbo.tblOrder o with (nolock)
WHERE o.BillEmail IN (SELECT DISTINCT o1.BillEmail 
        FROM dbo.tblOrder o1 with (nolock)
        WHERE year(o1.OrderDate)=YEAR(O.OrderDate)
    AND o.BillEmail IN (SELECT DISTINCT o2.BillEmail 
        FROM dbo.tblOrder o2 with (nolock)
        WHERE year(o2.OrderDate) < year(o.orderdate)
    AND o.BillEmail NOT LIKE '%@halloweencostumes.com'
    AND o.BillEmail NOT LIKE ''
GROUP BY YEAR(OrderDate)

这可以为您提供订单的每一年,不同客户的数量以及前一年购买的客户数量。但是,它的格式与您要填充的表的格式不同。