当前位置: 首页 > 面试题库 >

选择重叠的时间范围

杜起运
2023-03-14
问题内容

T-SQL DateTime问题。

我有一组时间范围。在这些时间范围内,可能会有一组重叠的时间范围,我称之为“封锁”时间。封锁的时间不会超过一天。我想要做的是分配时间以排除阻塞时间,基本上是给我没有“阻塞”的时间范围。可以肯定的是,阻塞时间不能超出时间范围。

示例:我工作时间是从上午9点到下午5点,在下午1点有30分钟的午餐时间。我想要2行的结果:9am至1pm和1.30pm至5pm。

如上所述,我有一组时间范围,因此在上面的示例中,工作时间每天可能会有所不同,休息时间及其持续时间可能会有所不同。

我猜就SQL而言,输入参数看起来像这样:

declare @timeranges table ( StartDateTime datetime, EndDateTime datetime )
declare @blockedtimes table ( StartDateTime datetime, EndDateTime datetime )

insert into @timeranges 
select '01 Jan 2009 09:00:00', '01 Jan 2009 17:00:00'
union select '02 Feb 2009 10:00:00', '02 Feb 2009 13:00:00'

insert into @blockedtimes 
select '01 Jan 2009 13:00:00', '01 Jan 2009 13:30:00'
union select '02 Feb 2009 10:30:00', '02 Feb 2009 11:00:00'
union select '02 Feb 2009 12:00:00', '02 Feb 2009 12:30:00'

结果集如下所示。

Start                   End
---------------------   ---------------------
'01 Jan 2009 09:00:00' '01 Jan 2009 13:00:00'
'01 Jan 2009 13:30:00' '01 Jan 2009 17:00:00'
'02 Feb 2009 10:00:00' '02 Feb 2009 10:30:00'
'02 Feb 2009 11:00:00' '02 Feb 2009 12:00:00'
'02 Feb 2009 12:30:00' '02 Feb 2009 13:00:00'

我可以使用游标或while循环来执行此操作,但是如果有人可以建议如何在不进行迭代的情况下执行此操作,那就太好了-谢谢。


问题答案:

我以为我会分享我最终确定的解决方案:

稍微调整一下临时表,因为我已经向@timeranges和@blockedtimes都添加了一个StartDate字段

declare @timeranges table ( StartDate datetime, StartDateTime datetime, EndDateTime datetime ) 
declare @blockedtimes table ( StartDate datetime, StartDateTime datetime, EndDateTime datetime )

无论如何,它似乎比发布的其他答案更简单-为大家的帮助加油:)

select 
    *
from
(
    -- first SELECT get start boundry
    select t.StartDateTime s, b.StartDateTime e
    from @timeranges t, @blockedtimes b
    where 
        -- same day and blocks overlaps timerange
        t.StartDate = b.StartDate and (t.StartDateTime <= b.EndDateTime and b.StartDateTime <= t.EndDateTime)
    and
        -- the following is the important bit for this SELECT   
        not exists (select 1 from @blockedtimes b2 where b2.StartDate = b.StartDate and b2.StartDateTime < b.StartDateTime)
union
    -- second SELECT get spikes ie middle
    select b1.EndDateTime s, b2.StartDateTime e
    from @timeranges t, @blockedtimes b1, @blockedtimes b2
    where 
        -- same day and blocks overlaps timerange
        t.StartDate = b1.StartDate and (t.StartDateTime <= b1.EndDateTime and b1.StartDateTime <= t.EndDateTime) 
    and 
        -- same day and blocks overlaps timerange
        t.StartDate = b2.StartDate and (t.StartDateTime <= b2.EndDateTime and b2.StartDateTime <= t.EndDateTime) 
    and 
        -- the following is the important bit for this SELECT
        b1.EndDateTime < b2.StartDateTime
union
    -- third SELECT get end boundry
    select b.EndDateTime s, t.EndDateTime e
    from @timeranges t, @blockedtimes b
    where 
        -- same day and blocks overlaps timerange
        t.StartDate = b.StartDate and (t.StartDateTime <= b.EndDateTime and b.StartDateTime <= t.EndDateTime)
    and 
        -- the following is the important bit for this SELECT
        not exists (select 1 from @blockedtimes b2 where b2.StartDate = b.StartDate and b2.StartDateTime > b.StartDateTime)
) t1


 类似资料:
  • 问题内容: 我有一个元组列表,每个元组都是一个。我正在尝试合并所有重叠的时间范围,并返回不同时间范围的列表。例如 这是我的实现方法。 我想弄清楚是否 是某些python模块中的内置函数可以更有效地做到这一点吗?要么 有没有达到相同目标的更Python方式? 感谢您的帮助。谢谢! 问题答案: 使用Pythonic可以提高效率的几种方法: 消除了构造,因为该算法应在主循环中删除重复项。 如果只需要遍历

  • 问题内容: 我在PostgreSQL 9.2中有一张表,看起来像这样(简化): 对于每个feature_id,可能会有多行,其时间范围由begin_time / end_time指定。它们可能重叠,但这是相对罕见的。我正在寻找一种快速的方法来查找所有具有/不具有 任何 重叠的feature_id 。 我尝试使用窗口函数来执行此操作,如下所示: …但这是行不通的: 该算法很简单:按begin_tim

  • 我们有一个Postgres表(物化视图),其中包含大约200万行,列如下: start_time(timestampz)-有索引 end_time(timestampz)-有索引 对于表中的每一行,我们希望添加一个包含以下内容的结果列: 1,如果行开始和结束时间范围与任何其他行重叠 0,如果行开始和结束时间范围不与任何其他行重叠 将每一行标记为具有重叠(1或0)的有效方法是什么? 编辑: 预期产出

  • 问题内容: 如何在MySQL中的日期范围之间选择数据。我的专栏是24小时的祖鲁时间格式。 尽管在这些时间段之间有数据,但不返回任何内容。我是否必须强制 “发件人” 和 “发件人” 字段中的值键入查询? 问题答案: 您需要更新日期格式:

  • 问题内容: 假设您有一个包含标识符,开始时间和结束时间的表。这些开始和结束时间可以是任何时间长度。开始时间总是早于结束时间。假设没有空值。 哪种查询会告诉我最“受欢迎”的时间,即每行中的两个范围与其他大多数行重叠的地方? 现实生活中的应用是,它是一个记录用户登录和注销时间的表格。我想编写一个查询,该查询将告诉我何时有最多并发用户登录,并查看这段时间。 谢谢你。 问题答案: 这是使用简单自连接和a的

  • 问题内容: 我已经看到了许多解决方案来识别日期范围重叠的记录,还有其他一些合并重叠范围的示例。 但是,我对显示仅重叠发生范围的结果感兴趣。实际上,我有3个ProductID(并且只有3个将存在),并且我试图为每个客户查找所有3个日期的日期范围。 问题答案: 答案如下: 这是使用自连接来计算每个产品上不同产品的数量。您需要三种截然不同的产品,因此该子句正在执行此操作。 有三种截然不同的产品,直到其中