6

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

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

我有客户的电子邮件地址(电子邮件)、下的所有订单(订单 ID)以及下订单的日期(订单日期)。该表是 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。所以我不知道该怎么办。而且我认为它只是拉出适用客户的列表(即在输入的月份之前没有订购的客户),而不是像我最终想要的那样将它们全部计数并总计。

4

5 回答 5

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在这里

于 2013-06-21T20:07:25.077 回答
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

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

没有表名和结构,无法创建整个查询,但希望以上内容能给您一个开始

于 2013-06-21T20:06:41.677 回答
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 中完成。

于 2013-06-21T20:13:08.747 回答
0

对@Mark Ba​​nnister 的回答稍作修改。OP 的既定意图是在新客户下第一个订单的月份获取新客户的数量。OP 对“新客户”的定义令人困惑,因为他指出:

“新客户”是:(a) 在日期/月份之前从未订购过的人,以及 (b) 在日期/月份之后至少有一个订单的人(强调)

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

  1. 只下一个订单的客户
  2. 在同一日期/月份下达所有订单的客户

@Mark的解决方案正确(?)消除了这些客户,因为他的 SQL FIDDLE显示 Fred@home 不被视为新客户。

但是,OP 在他的帖子末尾还指出,“适用的客户”是:

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

因此,为了捕获所有新客户(我认为 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
于 2015-12-30T17:45:23.770 回答
-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) 
于 2016-02-10T22:13:55.687 回答