2017-06-12 93 views
3

我試圖找到如何從每分鐘記錄數據到數據庫的記錄設備中選擇每小時的第一行。SQL:如何查詢每小時只選擇第一行?

我的示例數據:

Val  Date_time 
1734618 2017-06-09 14:01:04 
1734609 2017-06-09 14:00:05 
1734601 2017-06-09 13:59:04 
1734593 2017-06-09 13:58:04 
... 
1734127 2017-06-09 13:02:04 
1734119 2017-06-09 13:01:04 
1734111 2017-06-09 13:00:05 
1734103 2017-06-09 12:59:04 

我的問題是,我不知道如何從每個小時實時數據查詢僅第一行,我不知道爲什麼我不能使用DATE_FORMAT()函數在Microsoft SQL服務器管理在自動完成文本建議中根本沒有這個功能。因爲沒有DATE_FORMAT()函數,我發現這個選擇每分鐘都不適用於我。

SELECT * 
FROM table 
WHERE Date_time IN (SELECT MIN(Date_time) AS Date_time 
       FROM table 
       GROUP BY DATE_FORMAT(Date_time,'%Y-%m-%d %H:%i')) 

我的例子輸出:2行

Val  Date_time 
1734609 2017-06-09 14:00:05 
1734111 2017-06-09 13:00:05 

任何想法,請幫助先生? 非常感謝您的幫助。

編輯:使用FORMAT()函數它的工作原理。

+1

'DATE_FORMAT'是MySQL的功能。 MS SQL Server 2012具有'FORMAT'功能。例如,'SELECT FORMAT(getdate(),'yyyy-MM-dd HH:MM:ss','en-US')' –

+0

謝謝你的工作。 –

回答

1

不要使用使用子查詢的解決方案,性能將受到影響,並且上面的當前4個示例會隨着時間的推移給您一個錯誤的結果(嘗試添加1734618,'2017-05-09 14:01:04')。這種方法更有效:

SELECT 
    TOP 1 WITH TIES 
    * 
FROM <yourtable> 
ORDER BY 
    row_number()over 
    (partition by dateadd(hour, datediff(hour, 0, Date_time),0) ORDER BY Date_time) 
+0

非常感謝你。這種方式已經過優化並且非常有效。即使它比其他人快一點,但至少是這樣。 –

+0

非常抱歉,現在沒有投票。順便說一句,我可以把你的答案**有用**這麼多。 –

0

試試這個

select * 
from table t1 inner join 
(select min(Date_time) as minDate_time from table 
group by convert(date,Date_time),CONVERT(VARCHAR(2), Date_time, 114)) t2 
on t.Date_time= t2.minDate_time 
+0

謝謝你的作品。你忘了t1't1.Date_time = t2.minDate_time' –

0

這應該這樣做:

SELECT * 
FROM table 
WHERE table.Date_time IN 
(SELECT MIN(table.Date_time) AS Date_time 
    FROM table 
    GROUP BY cast(table.Date_time as DATE), DatePart(HOUR,table.Date_time) 
) 
0
SELECT * 
FROM table 
WHERE Date_time IN ( 

SELECT MIN(Date_time) 
FROM table 
GROUP BY CONVERT(VARCHAR(8), Date_time, 112), DATEPART(HOUR,Date_time) 

) 

它會爲你工作。

0
;With cte(Val,Date_time) 
AS 
(
SELECT 1734618,'2017-06-09 14:01:04' Union all 
SELECT 1734609,'2017-06-09 14:00:05' Union all 
SELECT 1734601,'2017-06-09 13:59:04' Union all 
SELECT 1734593,'2017-06-09 13:58:04' Union all 
SELECT 1734127,'2017-06-09 13:02:04' Union all 
SELECT 1734119,'2017-06-09 13:01:04' Union all 
SELECT 1734111,'2017-06-09 13:00:05' Union all 
SELECT 1734103,'2017-06-09 12:59:04' 
) 
SELECT Val,Date_time2 As Date_time FROM 
(
SELECT Val,CASE WHEN DATEDIFF(HOUR,LagDate_time,Date_time)=1 Then Date_time ELSE NUll END AS Date_time2 
From 
(
SELECT *,Lag(Date_time, 1) OVER (ORDER BY Date_time,Val DESC) AS LagDate_time 
FROM cte) 
Dt) 
)Dt2 
WHERE Dt2.Date_time2 IS NOT NULL 
ORDER BY Dt2.Date_time2 DESC 

輸出

Val  Date_time 
1734609 2017-06-09 14:00:05 
1734111 2017-06-09 13:00:05