2011-02-15 17 views
118

como cuando hagoCómo tiempo de grupo por hora o por 10 minutos

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

¿Cómo puedo especificar el período de grupo?

MS SQL 2008

segunda edición

Estoy intentando

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

cambió% a 10/10. Es posible hacer que la salida Fecha y sin milisegundos?

Respuesta

157

finalmente se hace con

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

Lo hice 'REDONDO ((DATEPART (MINUTE, DT. [Fecha])/5), 0,1) * 5', de modo que cuando miro los datos está correlacionado con el intervalo de tiempo más cercano – hdost

+5

Año, mes y el día se puede simplificar a 'FECHA (DT. [Fecha])'. – Keelan

+0

@Keelan No funciona para mí, sin embargo CONVERT (date, DT. [Date]) sí. –

13

En T-SQL puede:

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

o

por el uso minutos DATEPART(mi, [Date])

o

por 10 minutos utilizan DATEPART(mi, [Date])/10 (como Timoteo sugirió)

+0

GROUP BY [Fecha], DATEPART (hh, [Fecha]) es un lío, no? – Cynede

+1

@nCdy Debería estar bien; de lo contrario, aparece un error "... inválido en la lista de selección porque no está contenido en una función de agregado ni en la cláusula GROUP BY" – tzup

+0

¿Cómo se agrupa por fecha completa y por horas en ¿al mismo tiempo? Solo estoy usando Min Date. – Cynede

11

Para un intervalo de 10 minutos, sería

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

Como ya fue mencionado por TZUP y Pieter888 ... para hacer un intervalo de horas, simplemente

GROUP BY DATEPART(HOUR, [Date]) 
+1

pero aquí agrupo los minutos del año 1980 con los minutos del 2011: S Necesito preocuparme por ello. – Cynede

+2

Luego necesita agrupar por año y mes y día y hora también ... –

+0

¿Sería el% de la matemática correcta? ¿No sería eso crear 10 grupos? Por ejemplo: 1% 10 = 9 2% 10 = 8 Ni siquiera sería necesariamente la agrupación cronológica correcta tampoco. Creo que solo una división normal sería correcta. A menos que% no sea un resto dividido en sql. – Steven

4

debe ser algo como

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

(No es 100% seguro de la sintaxis - Soy más un tipo de tipo Oracle)

En Oracle:

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

Mi solución es utilizar una función para crear una tabla con los intervalos de fecha y luego unirse a esta tabla para los datos Quiero grupo mediante el intervalo de fechas en la tabla . El intervalo de fecha se puede seleccionar fácilmente al presentar los datos.

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 
6

La respuesta original que dio el autor funciona bastante bien. Sólo para extender esta idea, se puede hacer algo como

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

que le permitirá al grupo por un período más largo después de 60 minutos, dicen 720, que es la mitad de un día, etc.

+0

¿Cuál sería la consulta de MySQL para lo anterior? – Biranchi

2

para MySQL:

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

Para SQL Server 2012, aunque creo que funcionaría en SQL Server 2008R2, utilizo el siguiente enfoque para obtener el tiempo de cortar hasta la milésima de segundo:

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

Esto funciona por:

  • Conseguir el número de milisegundos entre un punto fijo y tiempo objetivo:
    @ms = DATEDIFF(MILLISECOND, CAST(time AS DATE), time)
  • Tomando el resto de dividir esos milisegundos en rodajas de tiempo:
    @rms = @ms % @msPerSlice
  • Agregando el negativo de que resto al tiempo objetivo para obtener el tiempo rebanada:
    DATEADD(MILLISECOND, [email protected], time)

Desafortunadamente, como es este se desborda con microsegundos y unidades más pequeñas, por lo que los conjuntos de datos más grandes y finos necesitarían usar un punto fijo menos conveniente. No he comparado rigurosamente esto y no estoy en Big Data, por lo que su kilometraje puede variar, pero el rendimiento no fue notablemente peor que los otros métodos probados en nuestros equipos y conjuntos de datos, y el pago en conveniencia rebanar hace que valga la pena para nosotros.

10

Estoy muy tarde a la fiesta, pero esto no aparece en ninguna de las respuestas existentes:

group by dateadd(minute, datediff(minute, 0, DT.[Date])/10 * 10, 0) 
  • El 10 y minute términos se puede cambiar a cualquier número y datepart, respectivamente .
  • Es un valor datetime, que significa:
    • Funciona bien a través de largos intervalos de tiempo (ninguna colisión entre años o nada).
    • Incluyéndolo en la instrucción select dará a su salida una columna con salida bonita truncada en el nivel que especifique.
SELECT dateadd(minute, datediff(minute, 0, AA.[Date])/10 * 10, 0) as [Date_Truncated], 
    count(*) as [Records_in_Interval], 
    avg(Value) as [Average_Value] 
FROM [FRIIB].[dbo].[ArchiveAnalog] as AA 
GROUP BY dateadd(minute, datediff(minute, 0, AA.[Date])/10 * 10, 0) 
ORDER BY [Date_Truncated] 
+0

¿sería posible hacerlo desde una fecha de inicio específica? – Pylander

+0

@pylander Seguro. Simplemente coloque una cláusula 'where' antes del' group by'. – Michael