我有一个日期时间列,其日期时间值范围。我想创建另一个包含所有这些日期时间值的列,但要舍入到十分钟的时间段。
所以,像这样:
datetimesent | ten_minute_column
2012-06-11 18:27:58.000 | 2012-06-11 18:20:00.000
2012-06-15 15:19:08.000 | 2012-06-15 15:10:00.000
... |
我所拥有的最远的就是将它放入分钟插槽中。 我这样做了:
SELECT DatetimeSent,
DATEADD(Minute, DATEDIFF(Minute, 0, DatetimeSent), 0) AS Minute_bucket
FROM allrequests
但我需要十分钟的时段。
答案 0 :(得分:8)
试试这个:
select dateadd(minute, datepart(minute, datetimesent) / 10 * 10,
dateadd(hour, datediff(hour, 0,datetimesent), 0)) ten_minute_column
from
(select cast('2012-06-11 18:27:58.000' as datetime) datetimesent
union all
select cast('2012-06-15 15:19:08.000' as datetime)) a
答案 1 :(得分:3)
您可以使用许多功能执行此操作:
WITH D AS
( SELECT CURRENT_TIMESTAMP [DateField]
UNION ALL
SELECT DATEADD(MINUTE, 5, CURRENT_TIMESTAMP)
)
SELECT DATEADD(MINUTE, (10 * FLOOR(DATEPART(MINUTE, DateField) / 10.0)) - DATEPART(MINUTE, DateField), DATEADD(MINUTE, DATEDIFF(MINUTE, 0, DateField), 0)) AS RoundedDate
FROM D
这样做的要点是删除10分钟间隔后的分钟数,并从实际分钟数中扣除(扣除秒数)。
通过将某些功能移动到连接,可以稍微整理一下。但是,我认为这不会带来任何性能提升(根本没有进行任何测试)
;WITH T AS
( SELECT Number,
(10 * FLOOR(Number / 10.0)) - Number [RoundedDifference]
FROM ( SELECT ROW_NUMBER() OVER(ORDER BY Object_ID) - 1 [Number]
FROM sys.All_Objects
) n
WHERE Number < 60
), D AS
( SELECT CURRENT_TIMESTAMP [DateField]
UNION ALL
SELECT DATEADD(MINUTE, 5, CURRENT_TIMESTAMP)
)
SELECT DateField,
DATEADD(MINUTE, RoundedDifference, DATEADD(MINUTE, DATEDIFF(MINUTE, 0, DateField), 0)) [RoundedDate]
FROM D
INNER JOIN T
ON DATEPART(MINUTE, DateField) = Number
答案 2 :(得分:0)
假设永远没有毫秒,你可以用这种方式去掉分钟和秒,并对结果进行分组:
SELECT DATEADD(SECOND, -(CONVERT(INT, RIGHT(CONVERT(CHAR(2),
DATEPART(MINUTE, GETDATE())),1))*60)-(DATEPART(SECOND,GETDATE())), GETDATE());
这是一个查询,根据表中的最小和最大日期(或表的子集)获得正确的时隙数:
DECLARE @x TABLE(datetimesent DATETIME);
INSERT @x SELECT '2012-06-11 18:27:58.000'
UNION ALL SELECT '2012-06-15 15:19:08.000';
DECLARE @start SMALLDATETIME, @end SMALLDATETIME, @i INT;
SELECT @start = CONVERT(DATE, MIN(datetimesent)), @end = CONVERT(DATE,
MAX(datetimesent))
FROM @x
-- WHERE ...;
SELECT @i = DATEDIFF(DAY, @start, @end) * 144;
;WITH slots(ten_minute_column) AS
(
SELECT TOP (@i * 144) DATEADD(MINUTE, 10 * (ROW_NUMBER() OVER
(ORDER BY s1.[object_id])-1), @start)
FROM sys.all_columns AS s1
-- you may need to cross join to another table if this doesn't
-- provide enough rows. Depends on overall datediff...
)
SELECT x.datetimesent, slots.ten_minute_column
FROM @x AS x
INNER JOIN slots
ON x.datetimesent >= slots.ten_minute_column
AND x.datetimesent < DATEADD(MINUTE, 10, slots.ten_minute_column)
-- WHERE ...;
结果:
datetimesent ten_minute_column
----------------------- -------------------
2012-06-11 18:27:58.000 2012-06-11 18:20:00
2012-06-15 15:19:08.000 2012-06-15 15:10:00
答案 3 :(得分:0)
SELECT DatetimeSent,
Dateadd(ms, -Datepart(ms, Dateadd(minute, Datediff(minute, 0,
Dateadd(minute,
-Datepart(minute,
datetimesent)
%10,
datetimesent)), 0
)
), Dateadd(minute, Datediff(minute, 0, Dateadd(minute,
-
Datepart(
minute,
datetimesent
)%
10,
datetimesent
)), 0)) AS Minute_bucket
FROM allrequests