Как для группы Время, час или 10 минут


нравится, когда я делаю

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. можно ли сделать вывод даты без миллисекунд ?

9 135

9 ответов:

наконец-то покончила с

GROUP BY
DATEPART(YEAR, DT.[Date]),
DATEPART(MONTH, DT.[Date]),
DATEPART(DAY, DT.[Date]),
DATEPART(HOUR, DT.[Date]),
(DATEPART(MINUTE, DT.[Date]) / 10)

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

GROUP BY DATEADD(MINUTE, DATEDIFF(MINUTE, 0, date_column) / 10 * 10, 0)
  • The 10 и MINUTE термины могут быть изменены на любое число и DATEPART, соответственно.
  • это DATETIME значение что означает:
    • он отлично работает через длительные промежутки времени. (Нет никакого столкновения между годами.)
    • , включая его в SELECT заявление даст ваш выход a столбец с довольно усеченным выводом на указанном вами уровне.
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]

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

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

или

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

или

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

в течение 10-минутного интервала, вы бы

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

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

GROUP BY DATEPART(HOUR, [Date])

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

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

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

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

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

(не на 100% уверен в синтаксисе - я больше похож на оракула)

В Oracle:

SELECT timeslot, COUNT(*) 
FROM
(  
    SELECT to_char(l_time, 'YYYY-MM-DD hh24') timeslot 
    FROM
    (
        SELECT l_time FROM mytab  
    )  
) GROUP BY timeslot 

Для MySql:

GROUP BY
DATE(`your_date_field`),
HOUR(`your_date_field`),
FLOOR( MINUTE(`your_date_field`) / 10);

мое решение-использовать функцию для создания таблицы с интервалами дат, а затем присоединить эту таблицу к данным, которые я хочу сгруппировать, используя интервал дат в таблице. Интервал дат может быть легко выбран при представлении данных.

CREATE FUNCTION [dbo].[fn_MinuteIntervals]
    (
      @startDate SMALLDATETIME ,
      @endDate SMALLDATETIME ,
      @interval INT = 1
    )
RETURNS @returnDates TABLE
    (
      [date] SMALLDATETIME PRIMARY KEY NOT NULL
    )
AS
    BEGIN
        DECLARE @counter SMALLDATETIME
        SET @counter = @startDate
        WHILE @counter <= @endDate
            BEGIN
                INSERT INTO @returnDates VALUES ( @counter )
                SET @counter = DATEADD(n, @interval, @counter)
            END
        RETURN
    END

для SQL Server 2012, хотя я считаю, что это будет работать в SQL Server 2008R2, я использую следующий подход, чтобы сократить время до миллисекунды:

DATEADD(MILLISECOND, -DATEDIFF(MILLISECOND, CAST(time AS DATE), time) % @msPerSlice, time)

работает:

  • получение количества миллисекунд между фиксированной точкой и целевым временем:
    @ms = DATEDIFF(MILLISECOND, CAST(time AS DATE), time)
  • принимая остаток от деления этих миллисекунд на временные срезы:
    @rms = @ms % @msPerSlice
  • добавление отрицательного остатка к целевому времени чтобы получить время среза:
    DATEADD(MILLISECOND, -@rms, time)

к сожалению, поскольку это переполнение с микросекундами и меньшими единицами, поэтому большие, более тонкие наборы данных должны были бы использовать менее удобную фиксированную точку.

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