web-dev-qa-db-fra.com

Comment grouper l'heure par heure ou par 10 minutes

comme quand je fais

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

comment puis-je spécifier la période du groupe?

MS SQL 2008

2e édition

J'essaie

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

a changé% 10 à/10. est-il possible de produire une sortie de date sans millisecondes?

152
cnd

enfin fini avec

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

Je suis super en retard à la fête, mais cela n'apparaît dans aucune des réponses existantes:

GROUP BY DATEADD(MINUTE, DATEDIFF(MINUTE, 0, date_column) / 10 * 10, 0)
  • Les termes 10 et MINUTE peuvent être modifiés en un nombre quelconque et DATEPART , respectivement.
  • C'est une valeur DATETIME, qui signifie:
    • Cela fonctionne très bien sur de longs intervalles. (Il n'y a pas de collision entre les années.)
    • L'inclure dans l'instruction SELECT donnera à votre sortie une colonne avec une jolie sortie tronquée au niveau que vous spécifiez.
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]
50
Michael

Dans T-SQL, vous pouvez:

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

ou

à la minute utiliser DATEPART(mi, [Date])

ou

par 10 minutes, utilisez DATEPART(mi, [Date]) / 10 (comme Timothy l'a suggéré)

16
tzup

Pour un intervalle de 10 minutes, vous feriez

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

Comme déjà mentionné par tzup et Pieter888 ... pour faire un intervalle d'une heure, juste

GROUP BY DATEPART(HOUR, [Date])
13
Timothy Khouri

Devrait être quelque chose comme

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

(Pas 100% sûr de la syntaxe - je suis plus du genre Oracle)

Dans Oracle:

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

La réponse originale de l'auteur donnait assez bien des œuvres. Juste pour prolonger cette idée, vous pouvez faire quelque chose comme

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

ce qui vous permettra de regrouper par une période plus longue que 60 minutes, par exemple 720, soit une demi-journée, etc.

6
Derek

Pour MySql:

GROUP BY
DATE(`your_date_field`),
HOUR(`your_date_field`),
FLOOR( MINUTE(`your_date_field`) / 10);
4
nobilist
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)
1
Rodas PT
select from_unixtime( 600 * ( unix_timestamp( [Date] ) % 600 ) ) AS RecT, avg(Value)
from [FRIIB].[dbo].[ArchiveAnalog]
group by RecT
order by RecT;

remplacez les deux 600 par le nombre de secondes que vous souhaitez grouper.

Si vous en avez souvent besoin et que la table ne change pas, comme le suggère le nom Archive, il serait probablement un peu plus rapide de convertir et de stocker la date (& heure) sous la forme d'un heure unique dans la table.

0
theking2

Ma solution consiste à utiliser une fonction pour créer une table avec les intervalles de date, puis associer cette table aux données que je souhaite regrouper à l'aide de l'intervalle de dates de la table. L’intervalle de dates peut alors être facilement sélectionné lors de la présentation des données.

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
0
user3193141

Je sais que je suis en retard au spectacle avec celui-ci, mais j’ai utilisé cette approche assez simple. Cela vous permet d’obtenir les tranches de 60 minutes sans problème d’arrondi.

Select 
   CONCAT( 
            Format(endtime,'yyyy-MM-dd_HH:'),  
            LEFT(Format(endtime,'mm'),1),
            '0' 
          ) as [Time-Slice]
0
jesse

Pour SQL Server 2012, bien que je pense que cela fonctionnerait dans SQL Server 2008R2, j'utilise l'approche suivante pour obtenir un découpage du temps à la milliseconde:

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

Cela fonctionne par:

  • Obtenir le nombre de millisecondes entre un point fixe et une heure cible:
    @ms = DATEDIFF(MILLISECOND, CAST(time AS DATE), time)
  • En prenant le reste de la division de ces millisecondes en tranches de temps:
    @rms = @ms % @msPerSlice
  • Ajouter le négatif de ce reste au temps cible pour obtenir le temps de tranche:
    DATEADD(MILLISECOND, -@rms, time)

Malheureusement, comme c'est le cas avec des microsecondes et des unités plus petites, des ensembles de données plus volumineux et plus fins devraient utiliser un point fixe moins pratique.

Je n'ai pas rigoureusement comparé cela et je ne fais pas partie du Big Data. Votre kilométrage peut donc varier, mais les performances ne sont pas pires que celles des autres méthodes testées sur nos équipements et ensembles de données. pour nous.

0
tychon