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

SQL中时间段的相交和合并

劳华灿
2023-03-14
问题内容

我想实现 .NET的时间段库中
提供的类似功能,但要实现SQL中的类似功能

首先,我有一个表,其中有几行带有开始日期和结束日期,
我想像这样将它们合并在一起:

组合

然后,根据该结果和另一个来自不同表的结果,我想
找出它们两者之间的交集,像这样,但是只有2个输入
(找到两个中都存在的周期):

路口

一旦我有了交叉路口,便只是在上面总结时间。

在这里,我通过示例提供了一个SQL Fiddle及其预期的输出:

http://sqlfiddle.com/#!18/504fa/3


问题答案:

Sample data preparation

CREATE TABLE TableToCombine
    ([IdDoc] int IDENTITY(1,1), [IdEmployee] int, [StartDate] datetime, [EndDate] datetime)
;

INSERT INTO TableToCombine
    (IdEmployee, StartDate, EndDate)
VALUES
    (1, '2018-01-01 06:00:00', '2018-01-01 14:00:00'),
    (2, '2018-01-01 11:00:00', '2018-01-01 19:00:00'),
    (3, '2018-01-01 20:00:00', '2018-01-02 03:00:00'),
    (1, '2018-01-02 06:00:00', '2018-01-02 14:00:00'),
    (2, '2018-01-02 11:00:00', '2018-01-02 19:00:00')
;

CREATE TABLE TableToIntersect
    ([IdDoc] int IDENTITY(1,1), [OrderId] int, [StartDate] datetime, [EndDate] datetime)
;

INSERT INTO TableToIntersect
    (OrderId, StartDate, EndDate)
VALUES
    (1, '2018-01-01 09:00:00', '2018-01-02 12:00:00')
;

Query:

with ExpectedCombineOutput as (
    select
        grp, StartDate = min(StartDate), EndDate = max(EndDate)
    from (
        select
            *, sum(iif(cd between StartDate and EndDate, 0, 1))over(order by StartDate) grp
        from (
            select
                *, lag(EndDate) over (order by IdDoc) cd
            from
                TableToCombine
        ) t
    ) t
    group by grp
)

select 
    a.grp, StartDate = iif(a.StartDate < b.StartDate, b.StartDate, a.StartDate)
    , EndDate = iif(a.EndDate < b.EndDate, a.EndDate, b.EndDate)
from
    ExpectedCombineOutput a
    join TableToIntersect b on a.StartDate <= b.EndDate and a.EndDate >= b.StartDate

相交的时间间隔在CTE中合并。然后与您的intersectTable一起查找重叠的句点。如果两个周期重叠
a.StartDate < b.EndDate and a.EndDate > b.StartDate



 类似资料:
  • 问题内容: 这个问题已经在这里有了答案 : 如何将一个字段中的日期与另一个字段中的时间相结合-MS SQL Server (17个答案) 7年前关闭。 好的-我问了几个人,必须有一个简单的方法来做…。 我真的必须:1)转换为字符串,然后转换为datetime字段吗?2)使用DateAdd和DatePart先添加小时,然后是分钟,然后是秒..... 问题答案: 在SQL Server 2012中,我

  • 问题内容: 我根据员工的工作时间做一些报告。在某些情况下,数据包含两个单独的记录,这实际上是一个时间段。 这是该表的基本版本和一些示例记录: 数据: 在该示例中,最后两个记录在时间上是连续的。我想编写一个查询,该查询结合了所有相邻记录,因此结果集是这样的: 理想情况下,它还应该能够处理两个以上的相邻记录,但这不是必需的。 问题答案: 本文为您的问题提供了许多可能的解决方案 http://www.s

  • 问题内容: 假设我有以下内容的事件表,和。 我想知道X人花了多少时间做一个事件(事件可以互相覆盖)。 如果此人只有1个事件,则很简单: 如果此人有2个事件,那将很棘手。 我将为预期的结果设置一些方案。 场景1 这意味着他的结果应该是从1到5的datediff 方案2 这意味着他的结果应该是一些和 如何在sql查询中获得此结果?我只能想到一堆if语句,但是同一个人可以有n个事件,因此查询确实会造成混

  • 我可以通过以下方法将数据发送到Firebase FiRecovery文档: 1) 添加() 2) set() 我很清楚,如何将数据添加到Firestore中,其中没有任何混淆。但我的问题是,Firebase Firestore中的方法“set”有两个setOption,例如merge和mergefields。这两组选项之间的区别是什么,我认为这两个选项的作用是相同的。如何实现setOption“m

  • 我有一组可能重叠的输入日期范围。我想创建具有调整日期的新日期范围,而不是组合这些重叠的日期范围,例如: 最终应为: 有没有有效的方法用Java解决这个问题? 提前感谢! 更新:在我的第一个问题中,我没有提到我自己的方法,所以它是这样的:我简单地获取间隔的开始和结束日期,并将其添加到一个排序的集合中。之后,我会遍历集合并根据重新排序的日期创建新的间隔。

  • 问题内容: 我有一个数据集,其中包含对频率为2分钟的几周的观察。我想将时间间隔从2分钟增加到5分钟。问题在于,观察的频率并不总是相同的。我的意思是,从理论上讲,每10分钟应进行5次观察,但通常情况并非如此。请让我知道如何根据平均功能以及观察的时间和日期汇总观察。换句话说,基于每5分钟的汇总,而对于每5分钟的时间间隔,观察次数却不同。此外,我有时间戳格式的日期和时间。 示例数据: 预期成绩: 问题答