计算SQL中时间跨度中的出现次数

时间:2015-01-28 16:23:32

标签: sql-server coldfusion qoq

如果我有数据存储在数据库中那样。

fk    start    end
1     1000     1100
1     1030     1130
2     1000     1100

我如何编写查询,以便得到如下结果:

fk    timeslot    occurences
1     1000        1
1     1030        2
1     1100        1
2     1000        1
2     1030        1

你可以告诉我,我以30分钟的增量工作。我可以实现这个服务器端但是它要求我运行查询查询或者每次都在计算两次之间的行时命中数据库。如果我可以在1个查询中收集这些信息,那么整个系统将会更快。

FK是我保留的资源的ID。

基本上我想让用户根据数据库中的出现次数知道剩余多少个开放点,如果可能的话多次击中数据库。如果我必须每天增加30分钟,那么QoQ就会受伤。

你也可以假设fk 1和2我有一个已知的最大开始时间和最大结束时间。如果重要的话。

1 个答案:

答案 0 :(得分:1)

您必须先以某种方式创建所有时间段,以便您可以检查哪些预订。递归CTE主要适用于这样的事情。因此,使用可以使用此CTE

DECLARE @MinStart TIME = '10:00:00'
DECLARE @MaxEnd TIME   = '12:00:00'

;WITH Timeslots AS (
   SELECT SlotStart = @MinStart, 
          SlotEnd = DATEADD(MINUTE, 30, @MinStart)

   UNION ALL

   SELECT SlotStart = DATEADD(MINUTE, 30, SlotStart), 
          SlotEnd = DATEADD(MINUTE, 30, SlotEnd)
   FROM Timeslots
   WHERE SlotEnd < @MaxEnd
)
SELECT *
FROM Timeslots

生成以下表格表达式:

SlotStart           SlotEnd
------------------------------------
10:00:00.0000000    10:30:00.0000000
10:30:00.0000000    11:00:00.0000000
11:00:00.0000000    11:30:00.0000000
11:30:00.0000000    12:00:00.0000000

这些是10:0012:00之间的所有时段。

您现在可以使用此查询:

;WITH Timeslots AS (
  ... cte statement here ...
)
SELECT fk, COUNT(fk) AS occurrences, t.SlotStart, t.SlotEnd
FROM #Reservations AS r
INNER JOIN Timeslots AS t ON t.SlotStart >= r.start AND t.SlotEnd <= r.[end]
GROUP BY fk, t.SlotStart, t.SlotEnd

获得您想要的结果:

fk  occurrences SlotStart           SlotEnd
---------------------------------------------
1   1           10:00:00.0000000    10:30:00.0000000
1   2           10:30:00.0000000    11:00:00.0000000
1   1           11:00:00.0000000    11:30:00.0000000
2   1           10:00:00.0000000    10:30:00.0000000
2   1           10:30:00.0000000    11:00:00.0000000