tags:

views:

104

answers:

5

I have a table named activity with 2 columns:

when as datetime // last time i saw a user
guid as varchar  // a unique identifier for each user

This tables is used to track usage in a certain resource. Guid are created by the clients.

I want to be able to query how many new users I have in the last day/week/month. A new user is identified by a guid appearing in the activity table for the first time.

How can I do this in a single SQL statement?

update: The table contains an entry for every time a user is using the resource. So if he used 5 times, there will be 5 rows. Until a user uses the resource, i don't have his guid and there is no entry in table for him.

The result:

Thank you all, it helped a lot. For anyone interested, this is what I compiled from all your suggestions:

SET @duration=7;
SELECT COUNT(distinct guid) AS total_new_users FROM `activity`
    WHERE `when` >= DATE_SUB(CURDATE(),INTERVAL @duration DAY) AND guid NOT IN
    (
     SELECT guid
     FROM `activity`
     WHERE `when` < DATE_SUB(CURDATE(),INTERVAL @duration DAY)
    );
A: 

Need claraification. If when is not populated on creation, then just SELECT * FROM activity WHERE when IS null. But I'm not sure if that's what you mean.

adamcodes
@flex: I updated, hope it's more clarified now
Am
+1  A: 
SELECT COUNT(DISTINCT guid) 
FROM activity
WHERE guid NOT IN (
    SELECT DISTINCT guid FROM activity WHERE when < CURDATE() - INTERVAL 7 DAYS
)
AND when BETWEEN CURDATE() AND CURDATE() - INTERVAL 7 DAYS;

change the 7 days to how ever long.

Huy Tran
That will not only count *new* users I think...
fretje
I think @curtisk has the right answer.
fretje
yup. that's right. i was just about to post that.
Huy Tran
+4  A: 
select count(guid)as total_new_users
from activity
where when >= {last day/week/month}
and guid not in(select guid
from activity
where when < {last day/week/month})
curtisk
A: 
SELECT COUNT(DISTINCT guid) 
FROM ACTIVITY 
WHERE when BETWEEN CURDATE() AND CURDATE() - INTERVAL 7 DAYS
  AND guid NOT IN (SELECT distinct GUID FROM ACTIVITY WHERE when < (CURDATE() -7 DAYS))

That should do it.

jschoen
+2  A: 

I think what you want is:

select count(*) from (
  select guid,min(when) as first from activity group by guid 
  having first between curdate()-interval 7 day and curdate() )

You have to query the entire table because otherwise people will be counted as new for their first visit during the time period in question. This query finds the first time each guid was seen, then filters out those that aren't in the period.

Jim Garrison
@Jim: interesting approach! add the table though
curtisk
I think my MySQL is too old, it cant use the `DAYS` keyword. (ver 4.1.22).
Am
@Jim: I like this use of HAVING. For +1, please do correct the syntax, adding the table as curtisk asked ("FROM activity") and singularizing the unit of INTERVAL ("7 DAY").
pilcrow
@pilcrow (nice handle) I have corrected the sql as you suggested
Jim Garrison
I cant upvote this for some reason, +1 just for showing me the `having` concept.
Am