2

I've been working on this and I don't think I'm doing it right. |D

Our database doesn't keep track of how many customers we retain so we looked for an alternate method. It's outlined in this article. It suggests you have this table to fill in:

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

The table would go out to 2012 in the headers. I'm just saving space.

It tells you to find the total number of customers you had in your starting year. To do this, I used this query since our starting year is 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)

At the moment we just differentiate our customers by email address.

Then you have to search for the same names of customers who purchased again in later years (ours are 2009, 10, 11, and 12).

I came up with this. It should find people who purchased in both 2008 and 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)

So I'm just finding the customers who purchased in both those years. And then I'm doing an independent query to find those who purchased in 2008 and 2010, then 08 and 11, and then 08 and 12. This one finds 2008 and 2010 purchasers:

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)

So you see I have a different query for each year comparison. They're all unrelated. So in the end I'm just finding people who bought in 2008 and 2009, and then a potentially different group that bought in 2008 and 2010, and so on. For this to be accurate, do I have to use the same grouping of 2008 buyers each time? So they bought in 2009 and 2010 and 2011, and 2012?

This is where I'm worried and not sure how to proceed or even find such data.

Any advice would be appreciated! Thanks!

4

2 回答 2

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
于 2013-06-28T16:19:40.593 回答
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)

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

于 2013-06-28T15:48:30.317 回答