如何按小时或10分钟分组

时间:2011-02-15 10:45:46

标签: sql sql-server-2008 tsql group-by

像我做的那样

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

如何指定小组时段?

MS SQL 2008

第二次修改

我正在尝试

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

将%10更改为/ 10.是否可以在没有毫秒的情况下进行日期输出?

15 个答案:

答案 0 :(得分:187)

最后完成了

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

答案 1 :(得分:40)

我在派对上已经很晚了,但这并没有出现在任何现有的答案中:

GROUP BY DATEADD(MINUTE, DATEDIFF(MINUTE, 0, date_column) / 10 * 10, 0)
  • 10MINUTE字词可以分别更改为任意数字和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]

答案 2 :(得分:16)

在T-SQL中,你可以:

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

按分钟使用DATEPART(mi, [Date])

使用DATEPART(mi, [Date]) / 10 10分钟(就像蒂莫西建议的那样)

答案 3 :(得分:13)

间隔10分钟,你会

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

正如tzup和Pieter888已经提到的......要做一个小时的间隔,只需

GROUP BY DATEPART(HOUR, [Date])

答案 4 :(得分:7)

应该像

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 

答案 5 :(得分:6)

作者给出的原始答案非常好。只是为了扩展这个想法,你可以做类似

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

这将允许你分组更长的时间,然后是60分钟,比如720,这是半天等。

答案 6 :(得分:3)

对于MySql:

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

答案 7 :(得分:1)

select dateadd(minute, datediff(minute, 0, Date), 0),
       sum(SnapShotValue)
FROM [FRIIB].[dbo].[ArchiveAnalog]
group by dateadd(minute, datediff(minute, 0, Date), 0)

答案 8 :(得分:0)

我的解决方案是使用函数创建具有日期间隔的表,然后使用表中的日期间隔将此表连接到我要分组的数据。 在呈现数据时,可以轻松选择日期间隔。

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

答案 9 :(得分:0)

对于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)

不幸的是,因为这会溢出微秒和更小的单位,所以更大,更精细的数据集需要使用不太方便的固定点。

我没有对此进行严格的基准测试,而且我没有大数据,因此您的里程可能会有所不同,但性能并不比我们的设备和数据集上尝试的其他方法明显更差,以及开发人员在任意切片方面的便利性让我们觉得有价值。

答案 10 :(得分:0)

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的形式存储和存储在表格中可能会更快一些。

答案 11 :(得分:0)

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)

答案 12 :(得分:0)

我知道我迟到了这个节目,但是我使用了这个-非常简单的方法。这样一来,您就可以得到60分钟的片段,而没有任何舍入问题。

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

答案 13 :(得分:0)

如果您想要实际显示日期,并且想要有一个可变分组,并且想要能够将更大的时间范围指定为 60 分钟:

DECLARE @minutes int
SET @minutes = 90

SELECT
    DATEADD(MINUTE, DATEDIFF(MINUTE, 0, [Date]) / @minutes * @minutes, 0) as [Date],
    AVG([Value]) as [Value]
FROM [FRIIB].[dbo].[ArchiveAnalog]
GROUP BY
    DATEDIFF(MINUTE, 0, [Date]) / @minutes

答案 14 :(得分:0)

试试这个查询。它使一列。 (参考@nobilist 回答)

GROUP BY CAST(DATE(`your_date_field`) as varchar) || ' ' || CAST(HOUR(`your_date_field`) as varchar) || ':' || CAST(FLOOR(minute(`your_date_field`) / 10) AS varchar) || '0' AS date_format