这是我的SQL Server 2012表(没有固定的插入插件):
DateTime Value
2016-12-16 15:08:03.0740000 17,11233139
2016-12-16 15:08:02.0560000 17,8571434
2016-12-16 15:08:00.0410000 17,11233139
2016-12-16 15:07:58.6570000 17,93345451
2016-12-16 15:07:54.9970000 17,11538506
2016-12-16 15:07:53.5910000 17,93345451
2016-12-16 15:06:45.3220000 17,93650818
2016-12-16 15:06:44.1230000 18,65079308
2016-12-16 15:01:09.0470000 20,41208839
2016-12-16 15:01:05.4060000 19,58791161
2016-12-16 15:01:03.3970000 20,41208839
2016-12-16 15:01:00.4070000 19,73138046
2016-12-16 15:00:57.2230000 20,41208839
2016-12-16 15:00:21.0380000 20,51892471
2016-12-16 15:00:19.0270000 21,22100067
2016-12-16 14:42:45.1810000 20,40903473
2016-12-16 14:27:40.0050000 19,59401703
2016-12-16 14:20:40.2510000 18,65995026
2016-12-16 14:19:03.7750000 18,65995026
2016-12-16 14:01:55.0120000 17,93955994
2016-12-16 13:59:07.9490000 17,12454224
2016-12-16 13:59:06.1180000 16,39499474
我希望每小时只有一行,最近的时间是整整一小时。例如。对于小时14,这是与整个小时最接近的值:
2016-12-16 14:01:55.0120000 17,93955994
2016-12-16 13:59:07.9490000 17,12454224
第2行(53秒)与14:00:00之间的差异较小,因此应该采用此行。
我怎么能这样做?感谢
答案 0 :(得分:3)
使用min
窗口功能。
select datetimecol,value
from (
select t.*,min(datetimecol) over(partition by cast(datetimecol as date),datepart(hour,datetimecol)) mintmstmp
from tablename t
) x
where datetimecol=mintmstmp
编辑1:要获得指定日期特定小时的最接近值,请使用
select top 1 datetimecol,val
from (select t.*,
abs(datediff(second,'2016-12-16 14:00:00.0000000',datetimecol)) df
from tablename t
) x
order by df
编辑2:一个选项是使用递归cte生成给定日期的所有小时,并将其连接到现有表,以根据时间差获得最接近的时间戳。
with datetimes as (select cast('2016-12-16 00:00:00.0000000' as datetime2) dt
union all
select dateadd(hour,1,dt) from datetimes where dt < '2016-12-17 00:00:00.0000000')
select datetimecol,val,dt closest_to_hour
from (
select t.*,dt,
row_number() over(partition by dt order by abs(datediff(second,d.dt,datetimecol))) rn
from tablename t
join datetimes d on datepart(hour,d.dt) between datepart(hour,datetimecol) and datepart(hour,datetimecol)+1
and cast(d.dt as date) = cast(t.datetimecol as date)
--change this join condition per your specifications
) x
where rn = 1
<强> Sample Demo
强>
答案 1 :(得分:1)
WITH CTE_ClosestToTheHour AS (
SELECT DateTime, Value,
ROW_NUMBER() OVER (PARTITION BY DATEADD(HH,
DATEPART(HH, DateTime),
CAST(CAST(DateTime AS DATE) AS DATETIME)
)
ORDER BY
ABS(
DATEDIFF(ms, DateTime,
DATEADD(HH,
DATEPART(HH, DateTime),
CAST(CAST(DateTime AS DATE) AS DATETIME)
)
)
)
ASC
) AS RN
FROM table
)
SELECT *
FROM CTE_ClosestToTheHour
WHERE RN = 1
ORDER BY DateTime
答案 2 :(得分:0)
这会使用DATEADD
向日期添加30分钟,然后截断到最接近的小时。 ROW_NUMBER
函数用于在此日期进行分区,按此与实际日期时间之间的差异排序,然后仅为每个分区选择第一行:
;WITH CTE
AS
(
SELECT dt, val,
ROW_NUMBER() OVER
(PARTITION BY dateadd(hour,
datediff(hour, 0, dateadd(mi, 30, dt)), 0)
ORDER BY
ABS(DateDiff(ms, dt,dateadd(hour,
datediff(hour, 0, dateadd(mi, 30, dt)), 0)))) AS RN
FROM #T
)
SELECT *
FROM CTE
WHERE RN=1