2013-06-21 2 views
6

Я по какой-то причине смущаюсь по этому поводу.Подсчитайте новых клиентов за месяц

В принципе, я ищу для запроса, который будет найти число новых клиентов в месяц, начиная с 2010 года

У меня есть адрес электронной почты клиента (электронная почта), все заказы (OrderId), и что дата его размещения (OrderDate). Таблица tblOrder.

Я знаю, что «новый клиент» является: (а) кто-то, кто никогда не заказывал до того дата/месяц и (б), который имеет по крайней мере один заказ после дата/месяц

I «d хотят выход быть что-то вроде этого, в конце концов, с более простым способом быть лучше:

 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. Поэтому я не знаю, что с этим делать. И я думаю, что он просто набирает список применимых клиентов (то есть тех, кто не заказывал до ввода месяца), а не подсчитывает их все и суммирует их, как я в конечном итоге хочу.

ответ

2

Try:

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.

+0

Из того, что я могу сказать, это самый точный ответ, основанный на результатах, которые я получаю. Я не уверен, как это точно подтвердить, но на данный момент большое спасибо! – ash

+0

@spazzie: Хорошо, вы могли бы принять мое слово за это ...;) Более серьезно, если задействовано менее миллиона строк, вы можете сбросить таблицу в Excel, а затем проверить свои результаты там. –

+0

Да, это выглядит довольно хорошо. Спасибо! :) – ash

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 

Первой частью находит все клиент, первый заказ был в указанном месяце. Затем вам нужен только тот клиент, который ТАКЖЕ удовлетворил второе условие (заказанное после указанной даты)

Без имен таблиц и структур невозможно создать весь запрос, но надеемся, что приведенное выше должно дать вам немного начала

+0

Имя таблицы там ! «адрес электронной почты клиента (электронная почта), все размещенные заказы (OrderID) и дата, на которую он был помещен (OrderDate). Таблица tblOrder« но спасибо! Я обязательно посмотрю на это ближе. – ash

+0

Исправлен пример запроса – Sparky

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 с немного дополнительная работа.

0

Незначительное изменение ответа @Mark Bannister. Предполагаемое намерение OP состоит в том, чтобы зафиксировать количество новых клиентов к тому месяцу, в котором они разместили свой первый заказ.Определение OP для «нового клиента» сбивает с толку в том, что он указывает:

«новый клиент» является: (а) кто-то, кто никогда не заказывал до дата/месяц, и (б), который имеет по крайней мере один заказ после даты/месяц (курсив добавлен)

Может быть, это действительно то, что ОП хочет, но это было бы более точно было бы назвать «новый клиент, который становится повторяющимся покупателем в следующем месяце», поскольку это исключает :

  1. Клиенты, которые только разместить один заказ
  2. Клиенты, которые размещают все свои заказы в тот же день/месяц

@ решение Марка правильно (?) Устраняет эти клиенты, как his SQL FIDDLE показывает, что Фред @ дома не учитывается как новый клиент.

Однако OP также заявляет в конце своего поста, что «действующие клиенты» являются:

тех, кто не заказал перед введенным месяцем

Так, чтобы захватить все новые клиент (это то, что я думаю, что OP действительно стоит), мы все еще можем использовать приятное решение PIVOT от @ Mark, и все, что нам нужно сделать, это посмотреть на 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 
-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) 
Смежные вопросы