Sql 按时段分组
我有一张数据表Sql 按时段分组,sql,sql-server,tsql,stored-procedures,Sql,Sql Server,Tsql,Stored Procedures,我有一张数据表 [ProtocolName], [PacketsDate], [PacketsAmount], [Flows] 'UPD' | '01/13/2016 23:55:00' | 50 | 10 'UPD' | '01/14/2016 00:02:00' | 50 | 10 'UPD' | '01/14/2016 00:03:00' | 50 | 10 'UPD' | '01/14/2016 01:10:00' | 50 | 10 'TCP'
[ProtocolName], [PacketsDate], [PacketsAmount], [Flows]
'UPD' | '01/13/2016 23:55:00' | 50 | 10
'UPD' | '01/14/2016 00:02:00' | 50 | 10
'UPD' | '01/14/2016 00:03:00' | 50 | 10
'UPD' | '01/14/2016 01:10:00' | 50 | 10
'TCP' | '01/14/2016 00:00:00' | 50 | 10
'TCP' | '01/14/2016 00:03:00' | 50 | 10
'TCP' | '01/14/2016 00:10:00' | 50 | 10
'IPv6'| '01/13/2016 23:30:00' | 50 | 10
'IPv6'| '01/14/2016 00:03:00' | 50 | 10
'IPv6'| '01/14/2016 00:45:00' | 50 | 10
'IPv6'| '01/14/2016 00:50:00' | 50 | 10
'IPv6'| '01/14/2016 01:35:00' | 50 | 10
'IPv6'| '01/14/2016 01:33:00' | 50 | 10
我在存储过程中有一个自定义生成的带有句点的表
[DateFrom], [DateTo]
'01/13/2016 23:00:00' | '01/13/2016 23:30:00'
'01/13/2016 23:30:00' | '01/14/2016 00:00:00'
'01/14/2016 00:00:00' | '01/14/2016 00:30:00'
'01/14/2016 00:30:00' | '01/14/2016 01:00:00'
'01/14/2016 01:00:00' | '01/14/2016 01:30:00'
'01/14/2016 01:30:00' | '01/14/2016 02:00:00'
因此,在结果中,我需要查看下一列
[DateTo], SUM([UDP_PacketsAmount]), SUM([TCP_PacketsAmount]), SUM([IPv6_PacketsAmount]), SUM([UPD_Flows]), SUM([TCP_Flows]), SUM([IPv6_Flows])
'01/13/2016 23:30:00' | 0 | 0 | 50 | 0 | 0 | 10 |
'01/14/2016 00:00:00' | 50 | 50 | 0 | 10 | 10 | 0 |
'01/14/2016 00:30:00' | 100 | 50 | 50 | 20 | 10 | 10 |
'01/14/2016 01:00:00' | 0 | 0 | 100 | 0 | 0 | 20 |
'01/14/2016 01:30:00' | 50 | 0 | 0 | 10 | 0 | 0 |
'01/14/2016 02:00:00' | 0 | 0 | 100 | 0 | 0 | 20 |
这对我来说非常困难,我不知道从哪里开始。使用简单的
CASE WHEN…END
语句进行求和
SELECT DateTo,
SUM(CASE WHEN ProtocolName='UPD' THEN PacketsAmount END) AS UDP_PacketsAmount,
SUM(CASE WHEN ProtocolName='TCP' THEN PacketsAmount END) AS TCP_PacketsAmount,
SUM(CASE WHEN ProtocolName='IPv6' THEN PacketsAmount END) AS IPv6_PacketsAmount,
SUM(CASE WHEN ProtocolName='UPD' THEN Flows END) AS UPD_Flows,
SUM(CASE WHEN ProtocolName='TCP' THEN Flows END) AS TCP_PacketsAmount,
SUM(CASE WHEN ProtocolName='IPv6' THEN Flows END) AS IPv6_PacketsAmount
FROM TableName
Group BY DateTo
使用简单的
CASE WHEN…END
语句进行求和
SELECT DateTo,
SUM(CASE WHEN ProtocolName='UPD' THEN PacketsAmount END) AS UDP_PacketsAmount,
SUM(CASE WHEN ProtocolName='TCP' THEN PacketsAmount END) AS TCP_PacketsAmount,
SUM(CASE WHEN ProtocolName='IPv6' THEN PacketsAmount END) AS IPv6_PacketsAmount,
SUM(CASE WHEN ProtocolName='UPD' THEN Flows END) AS UPD_Flows,
SUM(CASE WHEN ProtocolName='TCP' THEN Flows END) AS TCP_PacketsAmount,
SUM(CASE WHEN ProtocolName='IPv6' THEN Flows END) AS IPv6_PacketsAmount
FROM TableName
Group BY DateTo
您可以使用条件聚合和
连接到周期表:
SELECT p.DateTo,
UDP_PacketsAmount = SUM(CASE WHEN ProtocolName = 'UDP' THEN PacketsAmount END),
TCP_PacketsAmount = SUM(CASE WHEN ProtocolName = 'TCP' THEN PacketsAmount END),
IPv6_PacketsAmount= SUM(CASE WHEN ProtocolName = 'IPv6' THEN PacketsAmount END),
UPD_Flows = SUM(CASE WHEN ProtocolName = 'UDP' THEN Flows END),
TCP_Flows = SUM(CASE WHEN ProtocolName = 'TCP' THEN Flows END),
IPv6_Flows = SUM(CASE WHEN ProtocolName = 'IPv6' THEN Flows END)
FROM tab t
RIGHT JOIN periods p
ON t.PacketsDate >= p.DateFrom AND t.PacketsDate < p.DateTo
GROUP BY p.DateTo
ORDER BY p.DateTo;
选择p.DateTo,
UDP_PacketsAmount=SUM(ProtocolName='UDP'然后PacketsAmount END时的情况),
TCP_PacketsAmount=SUM(ProtocolName='TCP'然后PacketsAmount END时的情况),
IPv6_PacketsAmount=SUM(ProtocolName='IPv6'然后PacketsAmount END时的情况),
UPD_Flows=SUM(当ProtocolName='UDP'然后流结束时的情况),
TCP_Flows=SUM(当ProtocolName='TCP'然后流结束时的情况),
IPv6_Flows=SUM(ProtocolName='IPv6'然后流结束时的情况)
从表t
右连接周期p
在t.PacketsDate>=p.DateFrom和t.PacketsDate
注:
DateFrom
和DateTo
重叠,所以我使用了[DateFrom,DateTo]范围
如果需要(DateFrom,DateTo),只需在t.PacketsDate>p.DateFrom和t.PacketsDate上更改,就可以使用条件聚合和连接到时段表:
SELECT p.DateTo,
UDP_PacketsAmount = SUM(CASE WHEN ProtocolName = 'UDP' THEN PacketsAmount END),
TCP_PacketsAmount = SUM(CASE WHEN ProtocolName = 'TCP' THEN PacketsAmount END),
IPv6_PacketsAmount= SUM(CASE WHEN ProtocolName = 'IPv6' THEN PacketsAmount END),
UPD_Flows = SUM(CASE WHEN ProtocolName = 'UDP' THEN Flows END),
TCP_Flows = SUM(CASE WHEN ProtocolName = 'TCP' THEN Flows END),
IPv6_Flows = SUM(CASE WHEN ProtocolName = 'IPv6' THEN Flows END)
FROM tab t
RIGHT JOIN periods p
ON t.PacketsDate >= p.DateFrom AND t.PacketsDate < p.DateTo
GROUP BY p.DateTo
ORDER BY p.DateTo;
选择p.DateTo,
UDP_PacketsAmount=SUM(ProtocolName='UDP'然后PacketsAmount END时的情况),
TCP_PacketsAmount=SUM(ProtocolName='TCP'然后PacketsAmount END时的情况),
IPv6_PacketsAmount=SUM(ProtocolName='IPv6'然后PacketsAmount END时的情况),
UPD_Flows=SUM(当ProtocolName='UDP'然后流结束时的情况),
TCP_Flows=SUM(当ProtocolName='TCP'然后流结束时的情况),
IPv6_Flows=SUM(ProtocolName='IPv6'然后流结束时的情况)
从表t
右连接周期p
在t.PacketsDate>=p.DateFrom和t.PacketsDate
注:
DateFrom
和DateTo
重叠,所以我使用了[DateFrom,DateTo]范围
如果您需要(DateFrom,DateTo),只需在t.PacketsDate>p.DateFrom和t.PacketsDate上更改,我使用UDF创建动态日期范围(如下所列)。我提供了给定的值,但可以使用参数,即@StartDate、@EndDate、@Increment
Select DateR1
,DateR2
,UDP_Packets = SUM([UDP_PacketsAmount])
,UDP_Packets = SUM([TCP_PacketsAmount])
,IPv6_Packets = SUM([IPv6_PacketsAmount])
,UPD_Flows = SUM([UPD_Flows])
,TCP_Flows = SUM([TCP_Flows])
,IPv6_Flows = SUM([IPv6_Flows])
From YourTableName A
Join (Select DateR1=RetVal,DateR2=DateAdd(MINUTE,30,RetVal) from [dbo].[udf-Create-Range-Date]('2016-01-13 23:00:00','2016-01-14 02:00:00','MI',30)) B
on PacketsDate Between DateR1 and DateR2 and PacketsDate<DateR2
Group By DateR1,DateR2
Order By DateR1
用于创建动态日期范围的自定义项
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
CREATE FUNCTION[dbo]。[udf CREATE Range Date](@DateFrom datetime、@DateTo datetime、@DatePart varchar(10)、@Incr int)
退换商品
@ReturnVal表(RetVal日期时间)
作为
开始
可日期为(
选择DateFrom=@DateFrom
联合所有
选择Case@DatePart
当'YY'时,然后添加日期(YY,@Incr,df.dateFrom)
当'QQ'时,然后添加日期(QQ,@Incr,df.dateFrom)
当'MM'时,然后添加日期(MM,@Incr,df.dateFrom)
当“WK”时,然后添加日期(WK,@Incr,df.dateFrom)
当'DD'之后是DateAdd(DD,@Incr,df.dateFrom)
当“HH”时,然后添加日期(HH,@Incr,df.dateFrom)
当'MI'时,然后添加日期(MI,@Incr,df.dateFrom)
当'SS'时,然后添加日期(SS,@Incr,df.dateFrom)
终点
从日期表DF
其中DF.DateFrom<@DateTo
)
插入到@ReturnVal(RetVal)中,从日期表中选择日期选项(maxrecursion 32767)
返回
终点
我使用自定义项创建动态日期范围(如下所列)。我提供了给定的值,但可以使用参数,即@StartDate、@EndDate、@Increment
Select DateR1
,DateR2
,UDP_Packets = SUM([UDP_PacketsAmount])
,UDP_Packets = SUM([TCP_PacketsAmount])
,IPv6_Packets = SUM([IPv6_PacketsAmount])
,UPD_Flows = SUM([UPD_Flows])
,TCP_Flows = SUM([TCP_Flows])
,IPv6_Flows = SUM([IPv6_Flows])
From YourTableName A
Join (Select DateR1=RetVal,DateR2=DateAdd(MINUTE,30,RetVal) from [dbo].[udf-Create-Range-Date]('2016-01-13 23:00:00','2016-01-14 02:00:00','MI',30)) B
on PacketsDate Between DateR1 and DateR2 and PacketsDate<DateR2
Group By DateR1,DateR2
Order By DateR1
用于创建动态日期范围的自定义项
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
CREATE FUNCTION[dbo]。[udf CREATE Range Date](@DateFrom datetime、@DateTo datetime、@DatePart varchar(10)、@Incr int)
退换商品
@ReturnVal表(RetVal日期时间)
作为
开始
可日期为(
选择DateFrom=@DateFrom
联合所有
选择Case@DatePart
当'YY'时,然后添加日期(YY,@Incr,df.dateFrom)
当'QQ'时,然后添加日期(QQ,@Incr,df.dateFrom)
当'MM'时,然后添加日期(MM,@Incr,df.dateFrom)
当“WK”时,然后添加日期(WK,@Incr,df.dateFrom)
当'DD'之后是DateAdd(DD,@Incr,df.dateFrom)
当“HH”时,然后添加日期(HH,@Incr,df.dateFrom)
当'MI'时,然后添加日期(MI,@Incr,df.dateFrom)
当'SS'时,然后添加日期(SS,@Incr,df.dateFrom)
终点
从日期表DF
其中DF.DateFrom<@DateTo
)
插入到@ReturnVal(RetVal)中,从日期表中选择日期选项(maxrecursion 32767)
返回
终点
它如何处理期间?它如何处理期间?