Reputation: 4787
I have some data related to customers and the number of transactions they perform every day. I would like to see how many "new" customers do we get each week. The data looks like the following:
Custnum Created Revenue
1 2014/10/23 30
4 2014/10/23 20
5 2014/10/23 40
2 2014/10/30 13
3 2014/10/30 45
1 2014/10/30 56
In the above (sample) data, we can see that customer with custnum
1 has transactions in consecutive weeks, I want only the new customers for the next week, ones that have never done business with us in the past. In other words, I want the number of totally new customers for each week. So the result should be:
CustCount Created
3 2014/10/23
2 2014/10/30
I tried using the following query:
select
count(distinct custnum),
DATEADD(wk, DATEDIFF(wk, 0, created), 0) as Date
from ORDERS
where created > '2013-01-01'
group by
DATEADD(wk, DATEDIFF(wk, 0, created), 0)
order by
DATEADD(wk, DATEDIFF(wk, 0, created), 0)
But this query gives me the number of unique customers each week, I want the number of new customers every week.
Any help will be much appreciated.
Upvotes: 2
Views: 4657
Reputation: 5944
I took these statements:
Do you want
CustCount Created
2 week1 -- customer 1 and 2
1 week2 -- customer 3
2 week3 -- customer 4 and 5
-- Option A
1 week4 -- customer 6 is new and 2 was not counted
-- or Option B
2 week4 -- customer 6 and 2;
-- since customer 2 did not order anything in week3
This query SELECT Custnum, DATEPART ( week , created) as WeekNumber from Revenues Order by Custnum
returns this output for the provided sample data
Custnum WeekNumber
1 31 -- counts
1 44 -- does not count, since customer already ordered once
2 36 -- counts
3 36 -- counts
3 44 -- does not count
4 43 -- counts
5 43 -- counts
5 45 -- does not count
To get only the first record for a customer (the new customer) you can do this:
SELECT Distinct Custnum, Min(Created) as Min_Created
FROM Revenues
GROUP BY Custnum
First i used the sql from grouping customer orders by week, which you can find at the old sqlfiddle . But then i decided to use
Select Count(Custnum) as CountCust
, DATEPART(week, Min_Created) as Week_Min_Created
FROM (
SELECT Distinct Custnum, Min(Created) as Min_Created
FROM Revenues Group By Custnum
) sq Group by DATEPART(week, Min_Created)
On my sql-server-2008-r2 this returns
CountCust Week_Min_Created
1 31 -- only customer 1
2 36 -- customer 2 and 3
2 43 -- customer 4 and 5
-- nothing for week 45 since customer 5 was already counted
This is the sample data i used
CREATE TABLE Revenues
(
Custnum int ,
Created datetime,
Revenue int
);
INSERT INTO Revenues (Custnum, Created, Revenue)
VALUES
(1, '20140801', 30),
(2, '20140905', 13), (3, '20140905', 45),
(4, '20141023', 20), (5, '20141023', 40),
(3, '20141030', 45), (1, '20141030', 56),
(5, '20141106', 60);
Upvotes: 4
Reputation: 3
A better design would be to store the date the customer signed up along with the rest of their information. Once that is done you can use the solution in the link below.
http://sqlfiddle.com/#!12/2caaa/1
Upvotes: 0
Reputation: 4585
Sounds like you want to work with a subset of ORDERS that only has each customer's first order date.
select
count(custnum),
DATEADD(wk, DATEDIFF(wk, 0, created), 0) as Date
from
(Select custnum, min(created) as created From Orders Group by custnum) o
where created > '2013-01-01'
group by
DATEADD(wk, DATEDIFF(wk, 0, created), 0)
order by
DATEADD(wk, DATEDIFF(wk, 0, created), 0)
Upvotes: 3
Reputation: 4214
You can add a where clause such that the custnum does not exist in before a week, something like
custnum not in (select custnum from orders where created < (start date of week))
Pseudo code since I am not really familiar with sql server functions
Upvotes: 0