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

学校假期设置中的重叠差距和孤岛

颜经艺
2023-03-14
问题内容

我必须使用此periods表:

期间

id  | starts_on  |  ends_on   
----+------------+------------
678 | 2019-12-21 | 2019-12-22
534 | 2019-12-23 | 2020-01-04
679 | 2019-12-28 | 2019-12-29
  9 | 2020-01-01 | 2020-01-01
776 | 2020-01-04 | 2020-01-05
  7 | 2020-01-06 | 2020-01-06
777 | 2020-01-11 | 2020-01-12

它列出了学生不必上学的所有时间段。不幸的是,有些时期是重叠的。当在学校放假期间周末或公共假期发生时(每个人都有自己的时段行),就会发生这种情况。

在查找具有休止日期范围的行的帮助下,并在具有联邦州的国家/地区中,累加了它们的持续时间,空缺和离校假期,我最终得到了以下查询:

SELECT p.id, p.starts_on, p.ends_on, grp,
      (Max(ends_on) OVER (PARTITION BY grp) - Min(starts_on) OVER (PARTITION BY grp) 
      ) + 1 AS duration, Array_agg(p.id) OVER (PARTITION BY grp) 
FROM (SELECT p.*,
            Count(*) FILTER (WHERE prev_eo < starts_on - INTERVAL '1 day') OVER
                (PARTITION BY 1 
                  ORDER BY starts_on
                ) AS grp 
      FROM (SELECT p.*,
                  lag(ends_on) OVER (PARTITION BY 1 ORDER BY starts_on) AS prev_eo 
            FROM (SELECT p.id, p.starts_on, p.ends_on FROM periods p
            WHERE starts_on > '2019-12-15' AND
                  starts_on < '2020-01-15' ) p 
          ) p 
  ) p;

我得到什么

结果是

id  | starts_on  |  ends_on   | grp | duration |   array_agg   
----+------------+------------+-----+----------+---------------
678 | 2019-12-21 | 2019-12-22 |   0 |       15 | {678,534,679}
534 | 2019-12-23 | 2020-01-04 |   0 |       15 | {678,534,679}
679 | 2019-12-28 | 2019-12-29 |   0 |       15 | {678,534,679}
  9 | 2020-01-01 | 2020-01-01 |   1 |        1 | {9}
776 | 2020-01-04 | 2020-01-05 |   2 |        3 | {776,7}
  7 | 2020-01-06 | 2020-01-06 |   2 |        3 | {776,7}
777 | 2020-01-11 | 2020-01-12 |   3 |        2 | {777}

前三行为grp0(标识678、534和679)。

我想要的是

但是id 9、776和7也应该属于这个grp。不幸的是,它们重叠了。是否有可能得到这样的结果(我不在乎订单)?

id  | starts_on  |  ends_on   | grp | duration |   array_agg   
----+------------+------------+-----+----------+---------------
678 | 2019-12-21 | 2019-12-22 |   0 |       17 | {678,534,679,9,776,7}
534 | 2019-12-23 | 2020-01-04 |   0 |       17 | {678,534,679,9,776,7}
679 | 2019-12-28 | 2019-12-29 |   0 |       17 | {678,534,679,9,776,7}
  9 | 2020-01-01 | 2020-01-01 |   0 |       17 | {678,534,679,9,776,7}
776 | 2020-01-04 | 2020-01-05 |   0 |       17 | {678,534,679,9,776,7}
  7 | 2020-01-06 | 2020-01-06 |   0 |       17 | {678,534,679,9,776,7}
777 | 2020-01-11 | 2020-01-12 |   1 |        2 | {777}

我想知道总岛(grp 0)以天为单位的时间以及它包含的期间ID。

沙箱:https://rextester.com/SHVL41709


问题答案:

这是您其他问题的一个有趣的变体。问题在于,lag()仅查看前一行以检查是否有重叠。相反,您想查看所有前面的行。

幸运的是,您可以max()为此使用累加器:

SELECT p.id, p.starts_on, p.ends_on, grp,
      (Max(ends_on) OVER (PARTITION BY grp) - Min(starts_on) OVER (PARTITION BY grp) 
      ) + 1 AS duration, Array_agg(p.id) OVER (PARTITION BY grp) 
FROM (SELECT p.*,
            Count(*) FILTER (WHERE prev_eo < starts_on - INTERVAL '1 day') OVER
                (PARTITION BY 1 
                  ORDER BY starts_on
                ) AS grp 
      FROM (SELECT p.*,
                  MAX(ends_on) OVER (ORDER BY starts_on ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) AS prev_eo 
            FROM (SELECT p.id, p.starts_on, p.ends_on 
                  FROM periods p
                  WHERE starts_on > '2019-12-15' AND
                        starts_on < '2020-01-15'
                 ) p 
          ) p 
  ) p;

我不确定应该做什么PARTITION BY 1,但是我没有包括在内。

这是一个学期。

预料到您的下一个问题。这是一个挑战:如果开始时间相等,则累积最大值将不稳定。在这种情况下,您要么要删除重复项,要么要使累积最大值的排序保持稳定。



 类似资料:
  • 本文向大家介绍双边距重叠问题(外边距折叠)相关面试题,主要包含被问及双边距重叠问题(外边距折叠)时的应答技巧和注意事项,需要的朋友参考一下 参考回答: 多个相邻(兄弟或者父子关系)普通流的块元素垂直方向marigin会重叠 折叠的结果为: 两个相邻的外边距都是正数时,折叠结果是它们两者之间较大的值。 两个相邻的外边距都是负数时,折叠结果是两者绝对值的较大值。 两个外边距一正一负时,折叠结果是两者的

  • 本文向大家介绍外边距重叠是什么?重叠的结果是什么?怎么防止外边距重叠?相关面试题,主要包含被问及外边距重叠是什么?重叠的结果是什么?怎么防止外边距重叠?时的应答技巧和注意事项,需要的朋友参考一下 外边距重叠是什么? 外边距重叠指的是,当两个垂直外边距相遇时,它们将形成一个外边距。 重叠后的外边距的高度等于两个发生重叠的外边距的高度中的较大者。 发生的条件:属于同一个BFC的两个相邻元素上下marg

  • 问题内容: 我只是注意到,如果表中有一个标识列,则在我插入新行时,如果存在不连续性,SQL Server 2008会自动填充该序列。我的意思是,如果我的身份列我有1,2,5,6,如果我在表系统会将自动插入其他两行 3 ,7标识列。 你知道如何控制这种行为吗? 谢谢 问题答案: 这是已定义和记录的SQL Server行为,实际上,您无能为力。您想要更改什么? IDENTITY列将保证唯一且不断增加的

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

  • 问题内容: 我有以下问题: 事件有一个“开始”和“结束”时间以及一个数量。我两者都使用MySQL DATETIME。 现在,如果我有一个约束条件说“没有重叠的事件”,我需要进行一些检查等,但是如何设计呢?用户只需要5分钟左右的精度,但是我想用几秒钟来进行计算,因为那是“更简单” /“更清洁” 如果我有一个事件(A),其起始端为“ YYYY-MM-DD 12:00:00”-“ YYYY-MM-DD

  • 我正在尝试编写一个实体框架查询来查找日期之间的差距。我无法理解它。下面是数据的样子,我想找到差距,当我通过一组日期。 预期结果1 预期结果2 有谁能帮我做这件事吗?