sql - solano - Cómo agrupar el tiempo por hora o por 10 minutos
estado del tiempo (9)
Debería ser algo así como
select timeslot, count(*)
from
(
select datepart(''hh'', date) timeslot
FROM [FRIIB].[dbo].[ArchiveAnalog]
)
group by timeslot
(No estoy 100% seguro de la sintaxis, soy más un tipo de tipo de 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
como cuando lo hago
SELECT [Date]
FROM [FRIIB].[dbo].[ArchiveAnalog]
GROUP BY [Date]
¿cómo puedo especificar el período de grupo?
MS SQL 2008
2nd Edit
Lo estoy intentando
SELECT MIN([Date]) AS RecT, AVG(Value)
FROM [FRIIB].[dbo].[ArchiveAnalog]
GROUP BY (DATEPART(MINUTE, [Date]) / 10)
ORDER BY RecT
cambiado% 10 a / 10. ¿es posible hacer salida de fecha sin milisegundos?
En T-SQL puedes:
SELECT [Date]
FROM [FRIIB].[dbo].[ArchiveAnalog]
GROUP BY [Date], DATEPART(hh, [Date])
o
por minuto use DATEPART(mi, [Date])
o
por 10 minutos use DATEPART(mi, [Date]) / 10
(como sugirió Timothy)
La respuesta original que dio el autor funciona bastante bien. Solo para extender esta idea, puedes hacer algo como
group by datediff(minute, 0, [Date])/10
que le permitirá agrupar por un período más largo que 60 minutos, digamos 720, que es medio día, etc.
Llego 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)
- Los términos de
10
yminute
se pueden cambiar a cualquier número ydatepart
, respectivamente. - Es un valor de
datetime
ydatetime
, lo que significa:- Funciona bien en largos intervalos de tiempo (sin colisiones entre años ni nada).
- Si lo incluye en la instrucción de
select
, obtendrá una salida con una 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]
Mi solución es usar una función para crear una tabla con los intervalos de fecha y luego unir esta tabla a los datos que quiero agrupar utilizando 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
Para MySql:
GROUP BY
DATE(`your_date_field`),
HOUR(`your_date_field`),
FLOOR( MINUTE(`your_date_field`) / 10);
Para SQL Server 2012, aunque creo que funcionaría en SQL Server 2008R2, utilizo el siguiente enfoque para reducir el tiempo al milisegundo:
DATEADD(MILLISECOND, -DATEDIFF(MILLISECOND, CAST(time AS DATE), time) % @msPerSlice, time)
Esto funciona por:
- Obteniendo la cantidad de milisegundos entre un punto fijo y el tiempo objetivo:
@ms = DATEDIFF(MILLISECOND, CAST(time AS DATE), time)
- Tomando el resto de dividir esos milisegundos en segmentos de tiempo:
@rms = @ms % @msPerSlice
- Agregar el negativo de ese residuo al tiempo objetivo para obtener el tiempo de corte:
DATEADD(MILLISECOND, -@rms, time)
Lamentablemente, como esto 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 la comodidad del desarrollador para el corte arbitrario hace que valga la pena para nosotros.
Para un intervalo de 10 minutos, lo haría
GROUP BY (DATEPART(MINUTE, [Date]) / 10)
Como ya fue mencionado por tzup y Pieter888 ... para hacer un intervalo de una hora, solo
GROUP BY DATEPART(HOUR, [Date])
finalmente hecho con
GROUP BY
DATEPART(YEAR, DT.[Date]),
DATEPART(MONTH, DT.[Date]),
DATEPART(DAY, DT.[Date]),
DATEPART(HOUR, DT.[Date]),
(DATEPART(MINUTE, DT.[Date]) / 10)