Sql 将 5 分钟的 3 行分组为 15 分钟的一行
Sql Grouping 3 rows of 5 minutes into a single one of 15 minutes
我想将 5 分钟的 3 行分组为 15 分钟的单行,如果需要,我可以对第 3 行进行更新。
这是一个例子:
2016-07-29 14:00:00.000 2016-07-29 14:05:00.000
2016-07-29 14:05:00.000 2016-07-29 14:10:00.000
2016-07-29 14:10:00.000 2016-07-29 14:15:00.000
2016-07-29 14:15:00.000 2016-07-29 14:20:00.000
2016-07-29 14:20:00.000 2016-07-29 14:25:00.000
2016-07-29 14:25:00.000 2016-07-29 14:30:00.000
2016-07-29 14:30:00.000 2016-07-29 14:35:00.000
2016-07-29 14:35:00.000 2016-07-29 14:40:00.000
2016-07-29 14:40:00.000 2016-07-29 14:45:00.000
2016-07-29 14:45:00.000 2016-07-29 14:50:00.000
2016-07-29 14:50:00.000 2016-07-29 14:55:00.000
2016-07-29 14:55:00.000 2016-07-29 15:00:00.000
2016-07-29 15:00:00.000 2016-07-29 15:05:00.000
结果应该是:
2016-07-29 14:00:00.000 2016-07-29 14:15:00.000
2016-07-29 14:15:00.000 2016-07-29 14:30:00.000
2016-07-29 14:30:00.000 2016-07-29 14:45:00.000
2016-07-29 14:45:00.000 2016-07-29 15:00:00.000
...
谢谢! :)
基本上,您希望将每次截断为 15 分钟的间隔并将其用于聚合。像这样:
select distinct dateadd(minute, datediff(minute, 0, col1) / 15 * 15, 0),
dateadd(minute, datediff(minute, 0, col1) / 15 * 15 + 15, 0)
我使用 UDF 创建动态日期范围。您也可以使用 number/tally table
Declare @Date1 DateTime = '2016-07-29 14:00:00.000'
Declare @Date2 DateTime = '2016-07-30 00:00:00.000'
Select DateR1=RetVal,DateR2=DateAdd(MI,15,RetVal) from [dbo].[udf-Create-Range-Date](@Date1,@Date2,'MI',15) Where RetVal<@Date2
Returns
DateR1 DateR2
2016-07-29 14:00:00.000 2016-07-29 14:15:00.000
2016-07-29 14:15:00.000 2016-07-29 14:30:00.000
2016-07-29 14:30:00.000 2016-07-29 14:45:00.000
2016-07-29 14:45:00.000 2016-07-29 15:00:00.000
2016-07-29 15:00:00.000 2016-07-29 15:15:00.000
...
2016-07-29 23:30:00.000 2016-07-29 23:45:00.000
2016-07-29 23:45:00.000 2016-07-30 00:00:00.000
**
The UDF - Notice you can Ranges, Date Part, and Increment are
Parameters
**
CREATE FUNCTION [dbo].[udf-Create-Range-Date] (@DateFrom datetime,@DateTo datetime,@DatePart varchar(10),@Incr int)
Returns
@ReturnVal Table (RetVal datetime)
As
Begin
With DateTable As (
Select DateFrom = @DateFrom
Union All
Select Case @DatePart
When 'YY' then DateAdd(YY, @Incr, df.dateFrom)
When 'QQ' then DateAdd(QQ, @Incr, df.dateFrom)
When 'MM' then DateAdd(MM, @Incr, df.dateFrom)
When 'WK' then DateAdd(WK, @Incr, df.dateFrom)
When 'DD' then DateAdd(DD, @Incr, df.dateFrom)
When 'HH' then DateAdd(HH, @Incr, df.dateFrom)
When 'MI' then DateAdd(MI, @Incr, df.dateFrom)
When 'SS' then DateAdd(SS, @Incr, df.dateFrom)
End
From DateTable DF
Where DF.DateFrom < @DateTo
)
Insert into @ReturnVal(RetVal) Select DateFrom From DateTable option (maxrecursion 32767)
Return
End
-- Syntax Select * from [dbo].[udf-Create-Range-Date]('2016-10-01','2020-10-01','YY',1)
-- Syntax Select * from [dbo].[udf-Create-Range-Date]('2016-10-01','2020-10-01','DD',1)
-- Syntax Select * from [dbo].[udf-Create-Range-Date]('2016-10-01','2016-10-31','MI',15)
-- Syntax Select * from [dbo].[udf-Create-Range-Date]('2016-10-01','2016-10-02','SS',1)
使用递归 CTE..
;With cte(sdate,edate,maxdate)
as
(
select min(sdate),dateadd(minute,15,min(sdate) ),max(edate) as maxdate from #tt
union all
select dateadd(minute,15,sdate),dateadd(minute,15,edate) ,maxdate
from
cte
where
edate<=maxdate
)
select sdate,edate from cte
我想将 5 分钟的 3 行分组为 15 分钟的单行,如果需要,我可以对第 3 行进行更新。
这是一个例子:
2016-07-29 14:00:00.000 2016-07-29 14:05:00.000
2016-07-29 14:05:00.000 2016-07-29 14:10:00.000
2016-07-29 14:10:00.000 2016-07-29 14:15:00.000
2016-07-29 14:15:00.000 2016-07-29 14:20:00.000
2016-07-29 14:20:00.000 2016-07-29 14:25:00.000
2016-07-29 14:25:00.000 2016-07-29 14:30:00.000
2016-07-29 14:30:00.000 2016-07-29 14:35:00.000
2016-07-29 14:35:00.000 2016-07-29 14:40:00.000
2016-07-29 14:40:00.000 2016-07-29 14:45:00.000
2016-07-29 14:45:00.000 2016-07-29 14:50:00.000
2016-07-29 14:50:00.000 2016-07-29 14:55:00.000
2016-07-29 14:55:00.000 2016-07-29 15:00:00.000
2016-07-29 15:00:00.000 2016-07-29 15:05:00.000
结果应该是:
2016-07-29 14:00:00.000 2016-07-29 14:15:00.000
2016-07-29 14:15:00.000 2016-07-29 14:30:00.000
2016-07-29 14:30:00.000 2016-07-29 14:45:00.000
2016-07-29 14:45:00.000 2016-07-29 15:00:00.000
...
谢谢! :)
基本上,您希望将每次截断为 15 分钟的间隔并将其用于聚合。像这样:
select distinct dateadd(minute, datediff(minute, 0, col1) / 15 * 15, 0),
dateadd(minute, datediff(minute, 0, col1) / 15 * 15 + 15, 0)
我使用 UDF 创建动态日期范围。您也可以使用 number/tally table
Declare @Date1 DateTime = '2016-07-29 14:00:00.000'
Declare @Date2 DateTime = '2016-07-30 00:00:00.000'
Select DateR1=RetVal,DateR2=DateAdd(MI,15,RetVal) from [dbo].[udf-Create-Range-Date](@Date1,@Date2,'MI',15) Where RetVal<@Date2
Returns
DateR1 DateR2
2016-07-29 14:00:00.000 2016-07-29 14:15:00.000
2016-07-29 14:15:00.000 2016-07-29 14:30:00.000
2016-07-29 14:30:00.000 2016-07-29 14:45:00.000
2016-07-29 14:45:00.000 2016-07-29 15:00:00.000
2016-07-29 15:00:00.000 2016-07-29 15:15:00.000
...
2016-07-29 23:30:00.000 2016-07-29 23:45:00.000
2016-07-29 23:45:00.000 2016-07-30 00:00:00.000
**
The UDF - Notice you can Ranges, Date Part, and Increment are Parameters
**
CREATE FUNCTION [dbo].[udf-Create-Range-Date] (@DateFrom datetime,@DateTo datetime,@DatePart varchar(10),@Incr int)
Returns
@ReturnVal Table (RetVal datetime)
As
Begin
With DateTable As (
Select DateFrom = @DateFrom
Union All
Select Case @DatePart
When 'YY' then DateAdd(YY, @Incr, df.dateFrom)
When 'QQ' then DateAdd(QQ, @Incr, df.dateFrom)
When 'MM' then DateAdd(MM, @Incr, df.dateFrom)
When 'WK' then DateAdd(WK, @Incr, df.dateFrom)
When 'DD' then DateAdd(DD, @Incr, df.dateFrom)
When 'HH' then DateAdd(HH, @Incr, df.dateFrom)
When 'MI' then DateAdd(MI, @Incr, df.dateFrom)
When 'SS' then DateAdd(SS, @Incr, df.dateFrom)
End
From DateTable DF
Where DF.DateFrom < @DateTo
)
Insert into @ReturnVal(RetVal) Select DateFrom From DateTable option (maxrecursion 32767)
Return
End
-- Syntax Select * from [dbo].[udf-Create-Range-Date]('2016-10-01','2020-10-01','YY',1)
-- Syntax Select * from [dbo].[udf-Create-Range-Date]('2016-10-01','2020-10-01','DD',1)
-- Syntax Select * from [dbo].[udf-Create-Range-Date]('2016-10-01','2016-10-31','MI',15)
-- Syntax Select * from [dbo].[udf-Create-Range-Date]('2016-10-01','2016-10-02','SS',1)
使用递归 CTE..
;With cte(sdate,edate,maxdate)
as
(
select min(sdate),dateadd(minute,15,min(sdate) ),max(edate) as maxdate from #tt
union all
select dateadd(minute,15,sdate),dateadd(minute,15,edate) ,maxdate
from
cte
where
edate<=maxdate
)
select sdate,edate from cte