SQL计数数据每小时1/2

时间:2014-06-07 08:56:11

标签: asp.net sql sql-server

我有一个存储过程来计算每小时的数据,

Declare @DateTimeToFilter DATETIME;
--set @DateTimeToFilter = GetDate();
set @DateTimeToFilter = '6/5/14'

SET NOCOUNT ON;

WITH H ([Hour]) AS
(   SELECT  7       UNION 
    SELECT  8       UNION 
    SELECT  9       UNION 
    SELECT  10      UNION 
    SELECT  11      UNION 
    SELECT  12      UNION 
    SELECT  13      UNION 
    SELECT  14      UNION 
    SELECT  15      UNION 
    SELECT  16      UNION 
    SELECT  17      UNION 
    SELECT  18      UNION 
    SELECT  19
)
SELECT  H.[Hour],
    COUNT(T.BookingID) AS NoOfUsers
FROM    H
    LEFT JOIN tbl_Visitor T 
        ON H.[Hour] = DATEPART(HOUR, T.TimeofArrival) AND
        ((DATEDIFF(dd, T.TimeofArrival, @DateTimeToFilter) = 0) AND (DATEDIFF(mm, T.TimeofArrival, @DateTimeToFilter) = 0) AND 
                  (DATEDIFF(yy, T.TimeofArrival, @DateTimeToFilter) = 0))
GROUP BY H.[Hour];    

这会强制每小时返回的数据,无论是否有任何数据。

我怎样才能添加要添加的半小时数据,因此返回的数据看起来像。

Hour Count
7   0
7.5 0
8   0
8.5 0
9   0
9.5 0
10  4
10.5    0
11  0
11.5    0
12  0
12.5    0
13  0
13.5    0
14  5
14.5    0
15  2
15.5    0
16  2
16.5    0
17  0
17.5    0
18  0
18.5    0
19  0
19.5    0

数据以小提名的形式存储在数据库中,即2014-06-05 14:00:00

感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

您可以使用分钟而非小时:

with h ([Minute]) as (
  select 420 union all
  select 450 union all
  select 480 union all
  select 510 union all
  select 540 union all
  ...

将分钟数除以小时数:

select h.[Minute] / 60.0 as [Hour], ...

计算过滤数据的时间间隔的开始和停止时间:

... on T.TimeofArrival >= dateadd(minute, h.[Minute], @DateTimeToFilter) and
       T.TimeofArrival < dateadd(minute, h.[Minute] + 30, @DateTimeToFilter)

答案 1 :(得分:0)

下面是一个按半小时间隔分组的示例,可以轻松扩展其他间隔。我建议你避免将函数应用于WHERE子句中的列,因为这样可以防止这些列上的索引被有效使用。

DECLARE
      @DateTimeToFilter smalldatetime = '2014-06-05'
    , @IntervalStartTime time = '07:00:00'
    , @IntervalEndTime time = '20:00:00'
    , @IntervalMinutes int = 30;

WITH 
      t4 AS (SELECT n FROM (VALUES(0),(0),(0),(0)) t(n))
    , t256 AS (SELECT 0 AS n FROM t4 AS a CROSS JOIN t4 AS b CROSS JOIN t4 AS c CROSS JOIN t4 AS d)
    , t64k AS (SELECT ROW_NUMBER() OVER (ORDER BY (a.n)) AS num FROM t256 AS a CROSS JOIN t256 AS b)
    , intervals AS (SELECT DATEADD(minute, (num - 1) * @IntervalMinutes, @DateTimeToFilter) AS interval 
        FROM t64k
        WHERE num <= 1440 / @IntervalMinutes)
SELECT 
      interval
    , CAST(DATEDIFF(minute, @DateTimeToFilter, interval) / 60.0 AS decimal(3, 1)) AS Hour
    , COUNT(T.BookingID) AS NoOfUsers
FROM intervals
LEFT JOIN dbo.tbl_Visitor T 
    ON T.TimeofArrival >= intervals.interval
    AND T.TimeofArrival < DATEADD(minute, @IntervalMinutes, intervals.interval)
WHERE
    interval >= DATEADD(minute, DATEDIFF(minute, '', @IntervalStartTime), @DateTimeToFilter)
    AND interval < DATEADD(minute, DATEDIFF(minute, '', @IntervalEndTime), @DateTimeToFilter)
GROUP BY interval
ORDER BY Hour;