现在测试它:http ://sqlfiddle.com/#!3/a4e7a/2
我假设有一个用户表。性能提升的空间很大。例如,通过添加一个 where 子句来消除不重叠的范围。如果用可怕的 case 语句替换函数,它可能也会更快。
棘手的一点是要弄清楚两个时间跨度中有多少重叠的算法。我总是发现绘制案例图片很有用:
Case 1
|------|
|=======|
Case 2
|------|
|======|
Case 3
|-------|
|===|
和顺序相反的等价物。
事实证明,重叠是两个结束时间的最小值减去两个开始时间的最大值。(如果为负,则没有重叠)。我总是必须检查所有案例以重新说服自己这一点。
-- Function that determines how many minutes of overlap there are between two timespans
Create Function dbo.MinutesOverlap(
@Start1 as datetime, @End1 as datetime, @Start2 as datetime, @End2 as datetime
) Returns int As
Begin
Declare
@MaxStart As datetime,
@MinEnd As datetime,
@Ret int = 0
Set @MaxStart = Case When @Start1 > @Start2 Then @Start1 Else @Start2 End
Set @MinEnd = Case When @End1 > @End2 Then @End2 Else @End1 End
If @MaxStart < @MinEnd
Set @Ret = DateDiff(Minute, @MaxStart, @MinEnd)
Return @Ret
End
Select
u.UserID,
e.EventID,
Sum(dbo.MinutesOverlap(e.eventStart, e.eventEnd, a.availStart, a.availEnd))
From
Event e
Cross Join
User u
Left Outer Join
Available a
On u.UserID = a.UserID
Group By
u.UserID,
e.EventID