【问题标题】:Count # of occurrences in time span in SQL在 SQL 中计算时间跨度中的出现次数
【发布时间】:2015-01-28 16:23:31
【问题描述】:

如果我将数据存储在这样的数据库中。

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 我有一个已知的最大开始时间和最大结束时间。

【问题讨论】:

  • 那你有什么尝试?
  • 我在服务器端尝试过,我知道我可以。我在问是否可以在 MSSQL 中完成。我真的不知道从哪里开始使用 SQL。我认为这可以通过 CASE 语句来完成,但其中有 48 个效率不高。
  • 不确定你是如何在结果中得到timeslot
  • 所以 10:00 - 10:30 的时间段我可以直接调用 10:00,因为我知道它们是 30 分钟的时间段。因此,由于 fk 1 有两个预订,一个从 10:00 到 11:00,一个从 10:30 到 11:30。 10:00 - 10:30 有 1 个位置,10:30-11:00 有两个位置。有意义吗?

标签: sql-server coldfusion qoq


【解决方案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

【讨论】:

  • 今天要试试这个。谢谢。以前从未使用过WITH,也不知道它的存在。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-06
  • 1970-01-01
  • 2016-05-22
  • 2010-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多