2016-12-16 67 views
1

最接近列。這是我的SQL Server 2012表(無固定INTERVALL插入):SQL選擇充分小時

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 

到14:00:00的區別是用於行2(53秒),小,所以該行應該採取。

我該怎麼做?謝謝

+0

什麼是「每個小時」是什麼意思?有一天24小時。那麼每個小時你想要最近的唱片?即使差距很大?根據你的數據,最接近7點的記錄將是'15:08:03'的記錄。你想這樣或只有一定的時間嗎? –

回答

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

+0

不應該在分區上的字段是相反的順序? –

+0

你是對的@JuanCarlosOropeza ..我編輯它。 –

+0

這隻需要整小時的最小時間。但是如果前一小時的日期更接近呢?就像在OP的例子中一樣。 – Nebi

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 
+1

這給了您與我的答案相同的結果。 –

+0

不,它沒有。 –

+1

我建議你確認一下,而不是急匆匆地回答問題。 –

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 
+0

謝謝,但這隻會返回當前小時的最近值,而不是過去 –