SQL如何按时间段分组
我正在尝试按时间段对数据进行分组。每个时段为 5 分钟,我想查看从 08:00 到 18:00 每 5 分钟发生了什么。
我创建了一个表,其中包含该时间范围内的所有时间段。例如:
StartTime EndTime IsBusinessHours
08:40:00.0000000 08:45:00.0000000 1
08:45:00.0000000 08:50:00.0000000 1
08:50:00.0000000 08:55:00.0000000 1
08:55:00.0000000 09:00:00.0000000 1
等等。
Select
TimeDimension.[StartTime],
TimeDimension.[EndTime],
activity.[Description],
activity.[StartTime]
From
TimeDimension
Full Outer Join Activity
on (
Convert(varchar,activity.StartTime,108) >= Convert(varchar,TimeDimension.starttime, 108)
And Convert(varchar,activity.StartTime,108) <= Convert(varchar,TimeDimension.endtime, 108)
)
Where
activity.Date = @DateParam
And TimeDimension.isbusinesshours = 1
我希望数据按 5 分钟时间段分组,但我得到的是:
08:20:00.0000000 08:25:00.0000000 Some activity
08:30:00.0000000 08:35:00.0000000 Some activity
08:45:00.0000000 08:50:00.0000000 Three activities in this time period. First
08:45:00.0000000 08:50:00.0000000 Three activities in this time period. Second
08:45:00.0000000 08:50:00.0000000 Three activities in this time period. Third
当我想看到的是:
08:20:00.0000000 08:25:00.0000000 Some activity
08:25:00.0000000 08:30:00.0000000 NULL
08:30:00.0000000 08:35:00.0000000 Some activity
08:35:00.0000000 08:40:00.0000000 NULL
08:45:00.0000000 08:50:00.0000000 Three activities in this time period. First
08:45:00.0000000 08:50:00.0000000 Three activities in this time period. Second
08:45:00.0000000 08:50:00.0000000 Three activities in this time period. Third
这意味着我正在显示发生某些活动的时间段,而不是所有活动该范围内的时间段。我已将表称为 TimeDimension - 但我不确定这是否正确。直觉告诉我,这与分析服务有关。
谢谢
I'm trying to group data in time periods. Each period is 5 minutes and I'd like to see what was happening every 5 minutes from 08:00 to 18:00.
I have created a table that has all the time periods in that time range. E.g.:
StartTime EndTime IsBusinessHours
08:40:00.0000000 08:45:00.0000000 1
08:45:00.0000000 08:50:00.0000000 1
08:50:00.0000000 08:55:00.0000000 1
08:55:00.0000000 09:00:00.0000000 1
etc.
Select
TimeDimension.[StartTime],
TimeDimension.[EndTime],
activity.[Description],
activity.[StartTime]
From
TimeDimension
Full Outer Join Activity
on (
Convert(varchar,activity.StartTime,108) >= Convert(varchar,TimeDimension.starttime, 108)
And Convert(varchar,activity.StartTime,108) <= Convert(varchar,TimeDimension.endtime, 108)
)
Where
activity.Date = @DateParam
And TimeDimension.isbusinesshours = 1
I expect to have data grouped by 5 minute time periods, but what I get is:
08:20:00.0000000 08:25:00.0000000 Some activity
08:30:00.0000000 08:35:00.0000000 Some activity
08:45:00.0000000 08:50:00.0000000 Three activities in this time period. First
08:45:00.0000000 08:50:00.0000000 Three activities in this time period. Second
08:45:00.0000000 08:50:00.0000000 Three activities in this time period. Third
When what I'd like to see is:
08:20:00.0000000 08:25:00.0000000 Some activity
08:25:00.0000000 08:30:00.0000000 NULL
08:30:00.0000000 08:35:00.0000000 Some activity
08:35:00.0000000 08:40:00.0000000 NULL
08:45:00.0000000 08:50:00.0000000 Three activities in this time period. First
08:45:00.0000000 08:50:00.0000000 Three activities in this time period. Second
08:45:00.0000000 08:50:00.0000000 Three activities in this time period. Third
This means that I'm displaying time periods when some activities took place, rather than all time periods in that range. I have called a table TimeDimension - but I'm not sure whether this is correct. Gut feeling tells me that this is something to do with analysis services.
Thank you
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
注 1:使用 VARCHAR 执行 DATETIME 算术会产生较差的性能。
注 2:您有一个 OUTER JOIN,但有一个不考虑 NULL 的 WHERE 子句。
这就是我要使用的...
CTE 过滤
CTE 格式
独占与包含 EndTime
< EndTime
而不是<= EndTime
08:00 到 08:05
和08:05 到 08:10
等08 的奇怪间隔: 00 至08:04
等使用 Exclusive EndTime 值的替代方法是将 Activity.StartTime 值四舍五入到最接近的分钟。下面不使用字符串,而是使用 DateTime 函数...
-
DATEADD(分钟, DATEDIFF(分钟, 0, Activity.StartTime), 0)
Note 1: Doing DATETIME arithmetic using VARCHAR yields poor performance.
Note 2: You have an OUTER JOIN but then a WHERE clause that doesn't account for NULLs.
This is what I'd use...
CTE Filtering
CTE Formatting
Exclusive vs Inclusive EndTime
< EndTime
rather than<= EndTime
08:00 to 08:05
and08:05 to 08:10
, etc08:00 to 08:04
, etcAn alternative to using Exclusive EndTime values is to round your Activity.StartTime values to the nearest minute. Rather than using strings, the folowing does it using DateTime functions...
-
DATEADD(minute, DATEDIFF(minute, 0, Activity.StartTime), 0)
您说您想要对结果进行分组,但您没有将
GROUP
应用于查询。但是,如果您聚合结果,您将丢失您想要的不同信息(
Description
、StartDate
),除非它们与组中的其他记录匹配。正如 Scorpi0 评论的那样,您想要的输出示例将会很有用。
You say you want to group the results but you are not applying a
GROUP
to the query.However, if you aggregate the results you will lose the distinct information you are also wanting (
Description
,StartDate
) unless they match the other records in the group.As Scorpi0 commented, a sample of the output you want would be useful.
您在活动表上有一个过滤器:
activity.Date = @DateParam
。它阻止获取 TimeDimension 表的每一行。将过滤器放在连接子句中,您将看到所有数据。
或者你也可以这样做:
You have a filter on the activity table:
activity.Date = @DateParam
.It prevents from getting every row of the TimeDimension table. Put the filter in the join clause and you will see all your datas.
Or you can do also:
您需要将活动时间条件从常见的Where子句移至Join条件,如下所示:
You need to move activity time condition from common Where clause into Join condition, like so: