tags:

views:

1028

answers:

4

I have a table with timestamps. What is the proper query to get the records counts for each minute for the last hour.

I.e. if now is 2:25, I want to know how many record were between 1:25 and 1:26, 1:26 and 1:27, and so on, so I have 60 results.

A: 

SELECT COUNT (TS) from TABLE where TABLE.TS BETWEEN(starttime, endtime)

McWafflestix
Thanks, but this will give me the total count, or I have to run it 60 times. I need one query to give me the totals for each minute.
Sunny
+1  A: 

As you edited the question, I edit my answer. If I have understood you correctly, you want to look only at the past hour - that is, a timespan from one hour before the request is made to the current time. This is how I'd do it:

SELECT
    COUNT(yourTimeStamp)
FROM yourTable
WHERE DATEADD('hh', -1, GetDate()) <= yourTimeStamp 
    AND yourTimeStamp < GetDate()
GROUP BY DATEPART('mm', yourTimeStamp)

I am not entirely sure that the syntax is exact. When coding in MSSQL, I would use the CURRENT_TIMESTAMP for the current time, MINUTE instead of DATEPART etc, but you get the idea for the solution.

Tomas Lycken
+1 for the answer. it's not exactly what I need, so I'll rephrase the question. thanks.
Sunny
Also, there's no HOUR and MINUTE, but DATEPART.
Sunny
+1  A: 

DATEPART is what you're looking for:

declare @times table
(
    someTime datetime
)

INSERT INTO @Times (sometime) values ('jan 12 2008 12:23')
INSERT INTO @Times (sometime) values ('jan 12 2008 12:34')
INSERT INTO @Times (sometime) values ('jan 12 2008 12:35')
INSERT INTO @Times (sometime) values ('jan 12 2008 12:25')
INSERT INTO @Times (sometime) values ('jan 12 2008 12:02')
INSERT INTO @Times (sometime) values ('jan 12 2008 12:09')
INSERT INTO @Times (sometime) values ('jan 12 2008 12:35')


select DATEPART(mi,sometime) AS Minute, count(*) AS NumOccurances
from @Times
WHERE SomeTime BETWEEN @Lower AND @Upper
GROUP BY DATEPART(mi, sometime)
order by NumOccurances DESC

Result:

Minute  NumOccurances
35  2
2   1
9   1
23  1
25  1
34  1
p.campbell
This is better than Tomas' answer because using Hour() or the equivalent because the result would be misleading when the dataset had more than one day. Just remember that between is inclusive, it often better in these cases to says sometime >= lower and sometime < upper.
rfusca
My point was obviously that all parts of the dates that should be considered separately needed to be taken into account. I just wrote the Hour as an example, and thought it obvious that day, month and year also needs to be considered.
Tomas Lycken
+4  A: 

This will return a count of results for each minute (where you have records) in the last hour

SELECT DATEPART(n, time_stamp) AS minute, COUNT(*) as results
FROM table_name 
WHERE time_stamp > DATEADD(hh, -1, GETDATE())
GROUP BY DATEPART(n, time_stamp)

This may return less than 60 results, depending on the data. If you have to have 60 results, the query is slightly different. This uses a Common Table Expression to generate a list of 60 numbers and a correlated sub-query to get the results for each minute:

WITH numbers ( num ) AS (
    SELECT 1 UNION ALL
    SELECT 1 + num FROM numbers WHERE num < 60 )
SELECT num AS minute,
    (SELECT COUNT(*) AS results
    FROM table_name
    WHERE DATEPART(n, time_stamp) = num
    AND time_stamp > DATEADD(hh, -1, GETDATE())
FROM numbers

To see the results, replace DATEADD(hh, -1, GETDATE()) with DATEADD(mi, -15, GETDATE()) and you'll get the results for the last 15 minutes and 0 for other minutes.

Robin M
looks like right, thanks.
Sunny
Glad to help. Do you need to guarantee that the query returns 60 records every time?
Robin M
no, no need, thanks
Sunny
Ah, I've added that bit anyway!
Robin M