SQL Server 2012 : GROUP BY seconds, 分钟、小时

标签 sql sql-server-2012 group-by

我正在尝试按 DateTime 对 SQL Server 2012 中的记录进行分组。我在 stackoverflow 上找到了一个示例,它部分满足了我的要求,但问题是当它超出范围时,它的分组不正确。例如,如果我将分钟分组为 30 分钟,则结果是正确的(请参阅下面的查询和结果)。但如果我以 120 分钟为一组分组,我得到的结果完全相同。它在一小时内最多保持 60 分钟的分组(结果如下)。
问题是分组不能接受它的父 DateTime 元素(秒到分钟,分钟到小时,...,甚至秒到小时,...)。这是一种逻辑,因为我只在几分钟内检查,但我也希望看到它经过几个小时。也许使用 DATEADD(),但我无法让它工作。

有任何想法吗??

一个(小)例子来说明我的意思:

查询:

DECLARE @TimeInterval int, @StartTime DateTime, @EndTime Datetime
SET @TimeInterval = 30
SET @StartTime='2015-01-01T08:00:00Z'
SET @EndTime = '2015-01-05T10:00:00Z'

declare @T table
(
  Value datetime
);

insert into @T values ('2015-01-01T08:00:00');
insert into @T values ('2015-01-01T08:03:00');
insert into @T values ('2015-01-01T08:06:00');
insert into @T values ('2015-01-01T08:14:00');
insert into @T values ('2015-01-01T09:06:00');
insert into @T values ('2015-01-01T09:07:00');
insert into @T values ('2015-01-01T09:08:00');
insert into @T values ('2015-01-01T11:09:00');
insert into @T values ('2015-01-01T12:10:00');
insert into @T values ('2015-01-01T13:11:00');
insert into @T values ('2015-01-02T08:08:00');
insert into @T values ('2015-01-02T08:09:00');
insert into @T values ('2015-01-03T08:10:00');
insert into @T values ('2015-01-04T08:11:00');

SELECT DATEADD(MINUTE, @TimeInterval, Convert(Datetime,CONCAT(DATEPART(YEAR, Value),'-', DATEPART(MONTH, Value),
       '-', DATEPART(DAY, Value),' ', DATEPART(HOUR, Value),':', ((DATEPART(MINUTE, Value) / @TimeInterval) * @TimeInterval),':00'),120)) as Period, 
       ISNULL(COUNT(*), 0) AS NumberOfVisitors
FROM @T
WHERE Value >= @StartTime AND Value < @EndTime
GROUP BY Convert(Datetime,CONCAT(DATEPART(YEAR, Value),'-', DATEPART(MONTH, Value), '-', DATEPART(DAY, Value),' ',
         DATEPART(HOUR, Value),':',((DATEPART(MINUTE, Value) / @TimeInterval) * @TimeInterval),':00'),120)
ORDER BY Period 

30 分钟的结果
2015-01-01 08:30:00.000 | 4
2015-01-01 09:30:00.000 | 3
2015-01-01 11:30:00.000 | 1
2015-01-01 12:30:00.000 | 1
2015-01-01 13:30:00.000 | 1
2015-01-02 08:30:00.000 | 2
2015-01-03 08:30:00.000 | 1
2015-01-04 08:30:00.000 | 1

60 分钟的结果
2015-01-01 08:30:00.000 | 4
2015-01-01 09:30:00.000 | 3
2015-01-01 11:30:00.000 | 1
2015-01-01 12:30:00.000 | 1
2015-01-01 13:30:00.000 | 1
2015-01-02 08:30:00.000 | 2
2015-01-03 08:30:00.000 | 1
2015-01-04 08:30:00.000 | 1

提前致谢!

最佳答案

你不要datepart()以此目的。你想要分钟数。一种方法是使用 datediff() :

SELECT datediff(minute, @StartTime, value) / @TimeInterval as minutes,
       COUNT(*) AS NumberOfVisitors
FROM @T
WHERE Value >= @StartTime AND Value < @EndTime
GROUP BY datediff(minute, @StartTime, value) / @TimeInterval
ORDER BY minutes ;

SQL Server 执行整数除法,因此在这种情况下您不必担心余数。另外,COUNT(*)无法返回 NULL ,所以两者都不是 ISNULL()也不是 COALESCE()是合适的。

或者,要获取日期/时间值:
SELECT dateadd(day,
              datediff(minute, @StartTime, value) / @TimeInterval,
              @StartTime) as period,
       COUNT(*) AS NumberOfVisitors
FROM @T
WHERE Value >= @StartTime AND Value < @EndTime
GROUP BY datediff(minute, @StartTime, value) / @TimeInterval
ORDER BY period ;

关于SQL Server 2012 : GROUP BY seconds, 分钟、小时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35410814/

相关文章:

sql - 加入有限子查询?

sql - 使用 SQL 使用从左到右和从右到左混合的语言反转字符串中的字符?

c# - 这个简单的代码产生了死锁。包括简单的示例程序

sql - 使用 JOIN 和 RANK() 进行查询的性能问题

php - OrderBy 在应用 GroupBy Laravel 时不起作用

mysql - 为每个日期选择行的子集

sql-server - 如何在 SQL 中计算 IPv6 CIDR 路由前缀?

mongodb - 仅在 MongoDB 中满足特定条件时分组

c# - 将 LINQ Group By 数据传递到新的对象列表中

mysql - SQL - 昨天的日期