Как сгруппировать время по часам или по 10 минут - PullRequest
150 голосов
/ 15 февраля 2011

как когда я делаю

SELECT [Date]
  FROM [FRIIB].[dbo].[ArchiveAnalog]
  GROUP BY [Date]

как я могу указать групповой период?

MS SQL 2008

2-е редактирование

Я пытаюсь

SELECT MIN([Date]) AS RecT, AVG(Value)
  FROM [FRIIB].[dbo].[ArchiveAnalog]
  GROUP BY (DATEPART(MINUTE, [Date]) / 10)
  ORDER BY RecT

изменено% 10 на / 10. возможно ли сделать вывод даты без миллисекунд?

Ответы [ 12 ]

190 голосов
/ 24 февраля 2011

наконец сделано с

GROUP BY
DATEPART(YEAR, DT.[Date]),
DATEPART(MONTH, DT.[Date]),
DATEPART(DAY, DT.[Date]),
DATEPART(HOUR, DT.[Date]),
(DATEPART(MINUTE, DT.[Date]) / 10)
48 голосов
/ 30 января 2017

Я супер опоздал на вечеринку, но это не отражено ни в одном из существующих ответов:

GROUP BY DATEADD(MINUTE, DATEDIFF(MINUTE, 0, date_column) / 10 * 10, 0)
  • Термины 10 и MINUTE можно изменить налюбое число и DATEPART соответственно.
  • Это значение DATETIME, , что означает:
    • Работает нормально в течение длительного времениинтервалы.(Между годами нет коллизий.)
    • Включение его в оператор SELECT даст вашему выходу столбец с довольно обрезанным выводом на указанном вами уровне.
SELECT   DATEADD(MINUTE, DATEDIFF(MINUTE, 0, aa.[date]) / 10 * 10, 0) AS [date_truncated],
         COUNT(*) AS [records_in_interval],
         AVG(aa.[value]) AS [average_value]
FROM     [friib].[dbo].[archive_analog] AS aa
GROUP BY DATEADD(MINUTE, DATEDIFF(MINUTE, 0, aa.[date]) / 10 * 10, 0)
ORDER BY [date_truncated]
16 голосов
/ 15 февраля 2011

В T-SQL вы можете:

SELECT [Date]
  FROM [FRIIB].[dbo].[ArchiveAnalog]
  GROUP BY [Date], DATEPART(hh, [Date])

или

при использовании минут DATEPART(mi, [Date])

или

при использовании 10 минут DATEPART(mi, [Date]) / 10 (как предложил Тимофей)

13 голосов
/ 15 февраля 2011

За 10-минутный интервал вы бы

GROUP BY (DATEPART(MINUTE, [Date]) / 10)

Как уже упоминалось tzup и Pieter888 ... чтобы сделать интервал в час, просто

GROUP BY DATEPART(HOUR, [Date])
7 голосов
/ 15 февраля 2011

Должно быть что-то вроде

select timeslot, count(*)  
from 
    (
    select datepart('hh', date) timeslot
    FROM [FRIIB].[dbo].[ArchiveAnalog]  
    ) 
group by timeslot

(Не уверен на 100% в синтаксисе - я скорее парень из Oracle)

В Oracle:

SELECT timeslot, COUNT(*) 
FROM
(  
    SELECT to_char(l_time, 'YYYY-MM-DD hh24') timeslot 
    FROM
    (
        SELECT l_time FROM mytab  
    )  
) GROUP BY timeslot 
6 голосов
/ 01 июля 2015

Оригинальный ответ автора дал работы довольно неплохо. Просто чтобы расширить эту идею, вы можете сделать что-то вроде

group by datediff(minute, 0, [Date])/10

, что позволит вам группировать более длительный период, чем 60 минут, например, 720, что составляет полдня и т. Д.

4 голосов
/ 10 июля 2016

Для MySql:

GROUP BY
DATE(`your_date_field`),
HOUR(`your_date_field`),
FLOOR( MINUTE(`your_date_field`) / 10);
0 голосов
/ 04 апреля 2019

Я знаю, что опоздал на шоу с этим, но я использовал это - довольно простой подход.Это позволяет получить 60-минутные срезы без проблем с округлением.

Select 
   CONCAT( 
            Format(endtime,'yyyy-MM-dd_HH:'),  
            LEFT(Format(endtime,'mm'),1),
            '0' 
          ) as [Time-Slice]
0 голосов
/ 03 марта 2019
declare @interval tinyint
set @interval = 30
select dateadd(minute,(datediff(minute,0,[DateInsert])/@interval)*@interval,0), sum(Value_Transaction)
from Transactions
group by dateadd(minute,(datediff(minute,0,[DateInsert])/@interval)*@interval,0)
0 голосов
/ 21 февраля 2019
select from_unixtime( 600 * ( unix_timestamp( [Date] ) % 600 ) ) AS RecT, avg(Value)
from [FRIIB].[dbo].[ArchiveAnalog]
group by RecT
order by RecT;

замените два 600 на любое количество секунд, которое вы хотите сгруппировать.

Если вам это нужно часто, и таблица не меняется, как следует из названия Archive, вероятно, было бы немного быстрее преобразовать и сохранить дату (и время) как unixtime в таблице.

...