I have some difficulties with sql server to select max value in a column in interval of 1 hour within a time range.
My table look like this:
+----------+-------+---------------------+ | Id | Value | TimeStamp | +----------+-------+---------------------+ | 02030105 | 32.20 | 2019-04-21 08:21:50 | | 02030106 | 30.00 | 2019-04-21 08:36:40 | | 02030107 | 30.50 | 2019-04-21 08:51:10 | | 02030108 | 27.70 | 2019-04-21 09:31:23 | | 02030201 | 32.20 | 2019-04-21 09:50:30 | | 02030202 | 32.00 | 2019-04-22 10:19:50 | | 02030203 | 31.70 | 2019-04-22 10:34:26 | | 02030204 | 31.00 | 2019-04-22 11:33:04 | | 02030205 | 31.20 | 2019-04-22 11:47:50 | +----------+-------+---------------------+
How do I select max Value column in interval of 1 hour within a time range from
2019-04-21 08:21:50
to 2019-04-22 11:47:50
I want my output to be like this:
+----------+-------+---------------------+ | Id | Value | TimeStamp | +----------+-------+---------------------+ | 02030105 | 32.20 | 2019-04-21 08:21:50 | | 02030201 | 32.20 | 2019-04-21 09:50:30 | | 02030202 | 32.00 | 2019-04-22 10:19:50 | | 02030205 | 31.20 | 2019-04-22 11:47:50 | +----------+-------+---------------------+
Advertisement
Answer
You can use ROW_NUMBER()
in a subquery to assign a rank to each record withing groups of each records having the same timestamp (minutes and seconds excluded) ordered by value, and then filter on the top record in each group in the outer query:
SELECT id, value, timestamp FROM ( SELECT t.*, ROW_NUMBER() OVER( PARTITION BY dateadd(hour, datediff(hour, 0, timestamp), 0) ORDER BY value DESC ) rn FROM mytable t ) x WHERE rn = 1
id | value | timestamp ------: | :---- | :------------------ 2030105 | 32.20 | 2019-04-21 08:21:50 2030201 | 32.20 | 2019-04-21 09:50:30 2030202 | 32.00 | 2019-04-22 10:19:50 2030205 | 31.20 | 2019-04-22 11:47:50
If you want the average value within each 1h range as well, then:
SELECT id, value, timestamp, avg_value FROM ( SELECT t.*, ROW_NUMBER() OVER( PARTITION BY dateadd(hour, datediff(hour, 0, timestamp), 0) ORDER BY value DESC ) rn, AVG(value) OVER( PARTITION BY dateadd(hour, datediff(hour, 0, timestamp), 0) ) avg_value FROM mytable t ) x WHERE rn = 1