如果我有数据存储在数据库中那样。
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我有一个已知的最大开始时间和最大结束时间。如果重要的话。
答案 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:00
和12: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