Запрос для получения максимального значения на основе метки времени каждые 4 часа

#sql #sql-server

#sql #sql-сервер

Вопрос:

У меня есть таблица sql, которая хранит данные каждые 15 минут, но я хочу получать максимальное значение каждые 4 часа.

Это моя фактическая таблица:

  ---- ---- ---- ------------------------- 
| Id | F1 | F2 |        timestamp        |
 ---- ---- ---- ------------------------- 
|  1 | 24 | 30 | 2019-03-25 12:15:00.000 |
|  2 | 22 |  3 | 2019-03-25 12:30:00.000 |
|  3 |  2 |  4 | 2019-03-25 12:45:00.000 |
|  4 |  5 | 35 | 2019-03-25 13:00:00.000 |
|  5 | 18 | 23 | 2019-03-25 13:15:00.000 |
|  ' | '  |  ' | '                       |
| 16 | 21 | 34 | 2019-03-25 16:00:00.000 |
 ---- ---- ---- ------------------------- 
  

Результат, который я ищу, это:

  ---- ---- ---- 
| Id | F1 | F2 |
 ---- ---- ---- 
|  1 | 24 | 35 |1st 4 Hours
 ---- ---- ---- 
|  2 | 35 | 25 |Next 4 Hours
 ---- ---- ---- 
  

Я использовал запрос

 select max(F1) as F1,
       max(F2) as F2
from table
where timestamp>='2019/3/26 12:00:01'
  and timestamp<='2019/3/26 16:00:01'
  

и он возвращает значение первых 4 часов, но когда я увеличиваю временную метку с 4 часов до 8 часов, это все равно даст мне 1 максимальное значение, а не 2 за 4 часа.

Я пытался использовать предложение group by, но не смог получить ожидаемый результат.

Комментарии:

1. это за 4 часа, в час, за 24-часовой период, например 0, 4, 8 ,12,16,20:00 или каждые четыре часа с любой заданной начальной точки? например 1:24,5:24,9:24,13:24…

2. … и заканчивается ли диапазон дат (например, вы указываете даты начала / окончания, хотите только 24 часа и т.д.). Говорить «это моя таблица» здорово, когда вы показываете нам 6 строк. Но, несомненно, ваша таблица со временем будет увеличиваться.

3. @TJB Я регистрирую данные каждые 15 минут, поэтому данные будут в очень специфическом формате: 2:00, 2:15,2:30,3:00, 3:15. И мой начальный день был бы первым днем месяца, а конечный день был бы последним днем месяца. Данные не будут иметь никаких других временных меток, таких как 1: 24 и так далее.

4. @AaronBertrand Моими датами начала и окончания будут первый и последний день месяца. Я знаю, что таблица будет расти, и я учел это в своей архитектуре.

Ответ №1:

Это должно сработать

 SELECT   Max(f1), 
         Max(f2), datepart(hh,timestamp), convert(date,timestamp) 
FROM     TABLE 
WHERE    datepart(hh,timestamp)%4 = 0 
AND timestamp>='2019/3/26 12:00:01' 
AND      timestamp<='2019/3/26 16:00:01'
GROUP BY datepart(hh,timestamp), convert(date,timestamp)
ORDER BY convert(date,timestamp) asc
  

Комментарии:

1. Еще один WHERE после ORDER BY ? Это недопустимый синтаксис. WHERE Идет после предложений FROM and ON и перед GROUP BY , нигде больше, и их не может быть два.

2. @MatthewEvans Это работает, если мой диапазон дат равен 1 дню, но если я увеличу диапазон дат до месяца, который я ищу, то это просто даст мне только 6 значений.

3. @MatthewEvans Это очень близко, но я получаю результаты, отсортированные по часам, а не по дате. Итак, я хотел 2019-3-26 0,2019-3-26 4,2019-3-26 8……. но то, что я получаю, это 2019-3-26 0,2019-3-27 0,2019-3-28 0……… Надеюсь, это имеет смысл.

4. упорядочено по дате, затем по 4 часовым периодам

5. @MatthewEvans Я удалил часть даты (hh, временную метку) из предложения order by и получил то, что искал. Спасибо за помощь. Ценю это.

Ответ №2:

Вот относительно простой метод:

 select convert(date, timestamp) as dte,
       (datepart(hour, timestamp) / 4) * 4 as hour,
       max(F1) as F1,
       max(F2) as F2
from table
group by convert(date, timestamp), (datepart(hour, timestamp) / 4) * 4;
  

Это позволяет распределить дату и час по отдельным столбцам; вы можете использовать dateadd() , чтобы поместить их в один столбец.

Ответ №3:

Попробуйте этот запрос:

 declare @startingDatetime datetime = '2017-10-04 12:00:00';
select grp, max(F1) F1, max(F2) F2
from (
    select datediff(hour, @startingDatetime, [timestamp]) / 4 grp, *
    from MyTable
    where [timestamp] > @startingDatetime
) a group by grp
  

Комментарии:

1. Что такое startTime? Это столбец временной метки?