Reputation: 6338
Let's say I have a mysql table t:
DateTime timestamp;
int userid;
and I want to know how many total users I have over time. I have this:
2012-12-04 102
2012-12-05 101
2012-12-05 102
2012-12-05 103
2012-12-07 101
2012-12-08 104
So the first time 101 is seen is 12/5, the first time 104 is seen is 12/7, and so on. So I'd like this, for total-users-ever-seen by date:
2012-12-04 1
2012-12-05 3
2012-12-07 3
2012-12-08 4
(I don't care if there are extra dates in there with no new entries.)
The closest I've been able to get is the number of new users per day:
select distinct date, count(*) from
(select MIN(DATE(timestamp)) date from t group by userid order by date) t1 \
GROUP BY date;
which seems to work; the subquery gives the earliest timestamp for each userid, and the outer query combines by date. But how can I roll that up to get the total ever seen?
Oh yeah, I looked at MySQL query - find "new" users per day but it didn't seem to do what I'm looking for.
Upvotes: 2
Views: 2361
Reputation: 33935
SELECT x.timestamp
, COUNT(DISTINCT y.userid)
FROM t x
JOIN t y
ON y.timestamp <= x.timestamp
GROUP
BY timestamp;
GaryO, to understand why this works, just rewrite it this way...
SELECT DISTINCT x.timestamp, y.userid
FROM t x
JOIN t y
ON y.timestamp <= x.timestamp
ORDER
BY x.timestamp
, y.userid;
Using sgeddes's sqlfiddle, this gives us the following intermediate result:
+---------------------+--------+
| timestamp | userid |
+---------------------+--------+
| 2012-12-04 00:00:00 | 102 |
| 2012-12-05 00:00:00 | 101 |
| 2012-12-05 00:00:00 | 102 |
| 2012-12-05 00:00:00 | 103 |
| 2012-12-07 00:00:00 | 101 |
| 2012-12-07 00:00:00 | 102 |
| 2012-12-07 00:00:00 | 103 |
| 2012-12-08 00:00:00 | 101 |
| 2012-12-08 00:00:00 | 102 |
| 2012-12-08 00:00:00 | 103 |
| 2012-12-08 00:00:00 | 104 |
+---------------------+--------+
So in the final query, all we've done is COUNT this result when grouped by date.
Upvotes: 2
Reputation: 62831
Assuming I understand your requirements, you are looking to return the date and the count of users that they first appeared?
SELECT TimeStamp, COUNT(*)
FROM T JOIN (
SELECT MIN(TimeStamp) minDate, UserId
FROM t
GROUP BY UserId) T2 ON T.TimeStamp = T2.minDate AnD T.UserId = T2.UserId
GROUP BY T.TimeStamp
And the Fiddle: http://sqlfiddle.com/#!2/c1f5a/9
Good luck.
Upvotes: 1