使用间隔为15分钟的数字表对数字进行计数

时间:2019-02-11 08:04:36

标签: sql sql-server

计算出现次数最有效的方法是什么? 我发现数字表是根据开始时间和结束时间生成时序数据的最有效方法。 我已经创建了一个从0到100,000开始的数字表。

我已经生成了如下时序表:

Declare @Start datetime = '2018-01-01 00:00:00.000',@End datetime ='2018-02-01 00:00:00.000';

    SELECT
        DATEADD(MINUTE,Number*15,@Start) StartTime,
        [Number],
        DATEADD(MINUTE,(Number+1)*15,@Start) EndTime
    FROM dbo.Numbers 
    Where (Number+1)*15<=DATEDIFF(MINUTE,@Start,@End)
    Order By Number;

我的数据表如下:

Time                      ID
2018-01-01 00:00:01.000   1
2018-01-01 00:00:02.000   1
2018-01-01 00:15:00.000   124
2018-01-01 00:28:00.000   341
2018-01-01 00:26:00.000   111
2018-01-01 01:02:00.000   162
2018-01-01 04:09:00.000   110
2018-01-01 05:09:00.152   398
2018-01-01 08:12:00.000   902
2018-01-01 12:45:00.000   009
2018-01-01 13:23:00.000   000
2018-01-01 15:37:00.000   187

如何根据15分钟间隔计数时间?

2 个答案:

答案 0 :(得分:2)

您可以尝试使用cte递归创建日历表,然后进行外部联接

Declare @Start datetime = '2018-01-01 00:00:00.000',@End datetime ='2018-02-01 00:00:00.000';

;WITH CTE AS (
    SELECT @Start startTime,DATEADD(MINUTE,15,@Start) nextTime,@End endTime
    UNION ALL
    SELECT DATEADD(MINUTE,15,startTime),DATEADD(MINUTE,15,nextTime) nextTime,@End
    FROM CTE
    WHERE DATEADD(MINUTE,15,startTime) < @End
)
SELECT startTime,nextTime,COUNT(t1.ID)
FROM CTE c1 
LEFT JOIN T t1 on t1.Time BETWEEN c1.startTime and c1.nextTime
GROUP BY startTime,nextTime
option ( MaxRecursion 0 );

注意

CTE默认的最大递归为100,您可以设置option ( MaxRecursion 0 );

  

该语句终止。语句完成之前,最大递归100已用尽。

Sqlfiddle

答案 1 :(得分:0)

如何?只是一个普通的分组方式,因此您可以根据需要输入HAVING,SUM,AVERAGE等。一次运行顶部:

 create table TestTable 
 (
 Time datetime,
 ID int
 )
GO

insert into TestTable values('2018-01-01 00:00:01.000' ,  1)
insert into TestTable values('2018-01-01 00:00:02.000'  , 1)
insert into TestTable values('2018-01-01 00:15:00.000'   ,124)
insert into TestTable values('2018-01-01 00:28:00.000'   ,341)
insert into TestTable values('2018-01-01 00:26:00.000'   ,111)
insert into TestTable values('2018-01-01 01:02:00.000'   ,162)
GO

  CREATE FUNCTION [dbo].[RoundTime] (@Time datetime, @RoundTo float) RETURNS datetime
AS
BEGIN
    DECLARE @RoundedTime smalldatetime, @Multiplier float

    SET @Multiplier = 24.0 / @RoundTo

    SET @RoundedTime= ROUND(CAST(CAST(CONVERT(varchar, @Time, 121) AS datetime) AS float) * @Multiplier, 0) / @Multiplier

    RETURN @RoundedTime
END
GO

然后实际工作:

    DECLARE @startDate DATETime
    DECLARE @endDate DATETime

    SET @startDate = '2018-01-01'
    SET @endDate = GETDATE()

    DECLARE @dateAxis TABLE
    (
        dt DATETime
    )

    DECLARE @currentDate DATETime = @startDate

    WHILE @currentDate <= @endDate
    BEGIN
        INSERT INTO @dateAxis 
            SELECT @currentDate 

        SET @currentDate = DATEADD(Minute, 15, @currentDate)

    END

-- axis table
--select * from @dateAxis


SELECT 
  dt AS joinDt,
  dataset.MyCount
FROM
@dateAxis axis
LEFT JOIN
(
SELECT
 dbo.RoundTime([Time], 0.5) AS joinDt,
count(*) AS MyCount
FROM 
/*Your table here*/
TestTable tt
group by
 dbo.RoundTime([Time], 0.5)
) dataset
ON dataset.joinDt = axis.dt
ORDER BY 
axis.dt