Reputation: 2565
My SQL skills are way subpar and I am struggling with seemingly simple tasks. I am trying to get a report on the number of new users who visit our site for each date.
This is my Stats table:
| Date | userid |
+-------+-------+|
| date1 | user1 |
| date1 | user1 |
| date1 | user2 |
| date2 | user1 |
| date2 | user3 |
| date3 | user2 |
| date3 | user4 |
| date4 | user3 |
and I need to get a recordset where records would look something like this:
| Date | New users on that date |
+-------+------------------------+
| date1 | 2 |
| date2 | 1 |
| date3 | 1 |
| date4 | 0 |
I have a feeling I need to group the users distinctly per date but I get tripped on the actual implementation...
Upvotes: 0
Views: 72
Reputation: 116458
Try something like this, which will count the number of users which do not have a record for a previous date (SQL Fiddle demo):
SELECT Date, COUNT(*) as NewUsers
FROM Stats s1
WHERE NOT EXISTS
(
SELECT 1
FROM Stats s2
WHERE s2.userid = s1.userid
AND s2.Date < s1.Date
)
GROUP BY Date
Note, if you want to explicitly get the "0" value, you'll have to join back on the Stats table (SQL Fiddle demo):
SELECT s.Date, COALESCE(x.NewUsers, 0) AS NewUsers
FROM Stats s
LEFT OUTER JOIN
(
SELECT Date, COUNT(*) as NewUsers
FROM Stats s1
WHERE NOT EXISTS
(
SELECT 1
FROM Stats s2
WHERE s2.userid = s1.userid
AND s2.Date < s1.Date
)
GROUP BY Date
) x ON s.Date = x.Date
Alternatively, you can use COUNT over MIN, which might yield more performance with the right indexes (SQL Fiddle demo):
SELECT Date, COUNT(*)
FROM
(
SELECT MIN(Date) AS Date, userid
FROM Stats
GROUP BY userid
) x
GROUP BY Date
Upvotes: 1