[英]How to count records by day from specific hour in a range of date using SQL
我有一个datetime字段,我想按日期计算从8:00到9:00的一天中的日期范围内的所有记录(即:从:01/01/2012到:01/03/2012)。
例如,如果我有以下数据:
2012-01-01 08:26
2012-01-01 08:40
2012-01-01 09:26
2012-01-01 10:26
2012-01-02 08:06
2012-01-02 09:26
2012-01-02 09:40
2012-01-03 08:30
2012-01-03 10:26
结果应如下所示:
2012-01-01 2
2012-01-02 1
2012-01-03 1
编辑:这是我使用@gbn解决方案得到的(对我有用)
SELECT COUNT(*), convert(varchar(10),ScanDate,101)
FROM tblSingleBox (nolock)
WHERE DATEPART(Hour, scandate) = 8
and (scandate>='01/03/2012' and scandate<'01/05/2012')
GROUP BY convert(varchar(10),ScanDate,101)
order by convert(varchar(10),ScanDate,101)
SQL Server 2005及更早版本
SELECT
COUNT(*),
DATEADD(dd, DATEDIFF(dd, 0, SomeDateTime), 0)
-- SQL Server 2008: CAST(SomeDateTime AS date)
FROM
SomeTable
WHERE
DATEPART(Hour, SomeDateTime) = 8
GROUP BY
DATEADD(dd, DATEDIFF(dd, 0, SomeDateTime), 0);
-- SQL Server 2008: CAST(SomeDateTime AS date);
MySQL:
SELECT
COUNT(*),
DATE(SomeDateTime)
FROM
SomeTable
WHERE
HOUR(SomeDateTime) = 8
GROUP BY
DATE(SomeDateTime);
在这种情况下,最简单的代码和最快的代码可能会相差很大,并且可能取决于数据集的大小。
我怀疑最快的方法是加入日历和过滤器。 在这种情况下,我会在开始之前制作一个日历,但我建议您使用一个永久的日历...
CREATE TABLE #calendar (
date AS DATETIME
)
INSERT INTO #calendar SELECT '2011-12-31' UNION ALL SELECT '2012-01-01'
UNION ALL SELECT '2012-01-02' UNION ALL SELECT '2012-01-03'
UNION ALL SELECT '2012-01-04' UNION ALL SELECT '2012-01-05'
SELECT
calendar.date,
COUNT(*)
FROM
yourTable
INNER JOIN
#calendar AS calendar
ON yourTable.DateTimeField >= calendar.date + @minTime
AND yourTable.DateTimeField < calendar.date + @maxTime
WHERE
calendar.date >= @startDate
AND calendar.date <= @endDate
GROUP BY
calendar.date
这应该产生对索引最友好的查询,因此对于任何合理大小的数据而言,它都是非常有效的。
注意:
calendar.date + @Time
部分将有所不同。 您刚刚说过MS SQL Server,所以它更像是...
ON yourTable.DateTimeField >= DATEADD(hour, @minHour, calendar.date)
AND yourTable.DateTimeField < DATEADD(hour, @maxHour, calendar.date)
SQL Server 2005
IF OBJECT_ID('tempdb.dbo.#DATES') IS NOT NULL
DROP TABLE #DATES
CREATE TABLE #DATES
( LogDate smalldatetime )
INSERT INTO #DATES
( LogDate )
SELECT '2012-01-01 08:26'
UNION SELECT '2012-01-01 08:40'
UNION SELECT '2012-01-01 09:26'
UNION SELECT '2012-01-01 10:26'
UNION SELECT '2012-01-02 08:06'
UNION SELECT '2012-01-02 09:26'
UNION SELECT '2012-01-02 09:40'
UNION SELECT '2012-01-03 08:30'
UNION SELECT '2012-01-03 10:26'
UNION SELECT '2012-01-03 15:26'
DECLARE @nStartHour smallint
DECLARE @nEndHour smallint
SET @nStartHour = 15
SET @nEndHour = 16
SELECT CONVERT(varchar, LogDate, 101), COUNT(*)
FROM #DATES
WHERE DATEPART(hour,LogDate) BETWEEN @nStartHour AND (@nEndHour - 1)
GROUP BY CONVERT(varchar, LogDate, 101)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.