views:

108

answers:

2

My algorithm is for a 'hit counter', I am trying to not count the same person twice if that person came to the site twice in a time interval (For example if he comes twice in 5 minutes, I want to count it as 1 hit for this person)

Here's what my database looks like

UserIp     UserId          Date of user came
127.0.0.1   new.user.akb    26.03.2010 10:15:44
127.0.0.1   new.user.akb    26.03.2010 10:16:44
127.0.0.1   new.user.akb    26.03.2010 10:17:44
127.0.0.1   new.user.akb    26.03.2010 10:18:44
127.0.0.1   new.user.akb    26.03.2010 10:19:44
127.0.0.1   new.user.akb    26.03.2010 10:20:44
127.0.0.1   new.user.akb    26.03.2010 10:21:44
127.0.0.1   new.user.akb    26.03.2010 10:22:44
127.0.0.1   new.user.akb    26.03.2010 10:23:44

What I need to do is get number of distinct UserIPs from the table above that occured within a time interval. For example if I set the time interval for 5 minutes, and let's say that it starts at

26.03.2010 10:15:44

Then I will get 2 as the results, since there is 1 distinct value between 10:15 to 10:20 and , 1 other distinct value from 10:20 to 10:23,

For example if my interval is 3 minutes than the return result will be 3

Thanks.

+4  A: 
Codesleuth
+3  A: 

20000101 is some startdate:

select dateadd(mi, -d, '20000101') as d, num from
(select count(*) num, datediff(mi ,date_field, '20000101') / 5 * 5  d
from your_table
group by datediff(mi, date_field, '20000101') / 5 * 5 ) as a
order by d

And here's a C# solution using Linq:

var d1 = new Tuple<string, string, DateTime>("127.0.0.1", "new.user.akb", DateTime.Parse("26.03.2010 10:15:44"));
var d2 = new Tuple<string, string, DateTime>("127.0.0.1", "new.user.akb", DateTime.Parse("26.03.2010 10:16:44"));
var d3 = new Tuple<string, string, DateTime>("127.0.0.1", "new.user.akb", DateTime.Parse("26.03.2010 10:17:44"));
var d4 = new Tuple<string, string, DateTime>("127.0.0.1", "new.user.akb", DateTime.Parse("26.03.2010 10:18:44"));
var d5 = new Tuple<string, string, DateTime>("127.0.0.1", "new.user.akb", DateTime.Parse("26.03.2010 10:19:44"));
var d6 = new Tuple<string, string, DateTime>("127.0.0.1", "new.user.akb", DateTime.Parse("26.03.2010 10:20:44"));
var d7 = new Tuple<string, string, DateTime>("127.0.0.1", "new.user.akb", DateTime.Parse("26.03.2010 10:21:44"));
var d8 = new Tuple<string, string, DateTime>("127.0.0.1", "new.user.akb", DateTime.Parse("26.03.2010 10:22:44"));
var d9 = new Tuple<string, string, DateTime>("127.0.0.1", "new.user.akb", DateTime.Parse("26.03.2010 10:23:44"));
var list = new List<Tuple<string, string, DateTime>> {d1, d2, d3, d4, d5, d6, d7, d8, d9};

int interval = 3;
var query = list.GroupBy(data => ((int) (DateTime.Now - data.Item3).TotalMinutes)/interval*interval)
    .Select(data => new {IP = data.First().Item1});

foreach (var entry in query)
{
    Console.WriteLine(entry.IP);
}
Mikael Svenson
+1,I like the LINQ version, and the use of the Tuple class made me smile :)
Codesleuth