我正在尝试按时间段对数据进行分组。每个时段都是5分钟,我想看看从08:00到18:00每5分钟发生一次。
我创建了一个包含该时间范围内所有时间段的表。 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
等
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 - 但我不确定这是否正确。直觉告诉我这与分析服务有关。
谢谢
答案 0 :(得分:4)
注1:使用VARCHAR执行DATETIME算法会导致性能不佳。
注意2:您有一个OUTER JOIN,但是有一个不考虑NULL的WHERE子句。
这是我用的......
WITH
FilteredActivity AS
(
SELECT
Description,
DATEADD(DAY, -DATEDIFF(DAY, 0, StartTime), StartTime) AS StartTime
FROM
Activity
WHERE
Date = @DateParam
)
SELECT
TimeDimension.[StartTime],
TimeDimension.[EndTime],
activity.[Description],
activity.[StartTime]
FROM
TimeDimension
LEFT JOIN
FilteredActivity AS [Activity]
ON Activity.StartTime >= TimeDimension.StartTime
AND Activity.StartTime < TimeDimension.EndTime
WHERE
TimeDimension.isbusinesshours = 1
CTE过滤
CTE格式
独家与包容性EndTime
< EndTime
而不是<= EndTime
08:00 to 08:05
和08:05 to 08:10
等08:00 to 08:04
等没有奇怪的间隔
使用Exclusive EndTime值的另一种方法是将Activity.StartTime值四舍五入到最接近的分钟。不是使用字符串,而是使用DateTime函数进行操作...
- DATEADD(minute, DATEDIFF(minute, 0, Activity.StartTime), 0)
答案 1 :(得分:2)
您说您想要对结果进行分组,但未将GROUP
应用于查询。
但是,如果您汇总结果,则会丢失您想要的独特信息(Description
,StartDate
),除非它们与组中的其他记录匹配。
正如Scorpi0评论的那样,你想要的输出样本会很有用。
答案 2 :(得分:1)
活动表上有一个过滤器:activity.Date = @DateParam
。
它阻止获取TimeDimension表的每一行。将过滤器放在join子句中,您将看到所有数据。
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)
And activity.Date = @DateParam
)
Where TimeDimension.isbusinesshours = 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 TimeDimension.isbusinesshours = 1
And (activity.Date Is Null Or activity.Date = @DateParam)
答案 3 :(得分:1)
您需要将活动时间条件从公共Where子句移动到Join条件,如下所示:
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)
And activity.Date = @DateParam
)
Where
TimeDimension.isbusinesshours = 1