sql - 如何在 Postgresql 中查找多行之间的重叠日期范围?
问题描述
我有一张员工表,其中包含他们的职位、团队、团队负责人等信息。每一行都有一个valid_from
和valid_to
字段,它与其他规范组成一个特定的日期范围。如果任何信息发生更改,它将自动使用valid_from
= now() 创建一个新行,并将前一行设置为valid_to
= now() - 间隔“1 天”。
问题是这种自动行生成可以创建重叠的日期范围,因为它是从不同的电子表格生成的,我需要手动更正它们。所以我想写一个 sql 查询来找到这些重叠。
我从表中做了一个视图:
select
employee_id,
rank() over (partition by employee_id order by valid_from) as rank,
valid_from,
valid_to
from myTable
这给了我如下数据:
| employee_id | rank | valid_from | valid_to |
|-------------|------|------------|------------|
| 1000 | 1 | 2016-11-28 | 2017-06-30 |
| 1000 | 2 | 2017-07-01 | 2018-02-26 |
| 1000 | 3 | 2018-02-25 | 2018-03-12 |
| 1001 | 1 | 2016-11-28 | 2017-07-30 |
| 1001 | 2 | 2017-07-31 | 2017-07-31 |
| 1001 | 3 | 2017-08-01 | 2017-08-01 |
如果当前行日期范围与同一行中的任何其他行重叠,我想再添加一个具有真/假值或类似内容的列employee_id
:
| employee_id | rank | valid_from | valid_to | overlapp_exist |
|-------------|------|------------|------------|----------------|
| 1000 | 1 | 2016-11-28 | 2017-06-30 | false |
| 1000 | 2 | 2017-07-01 | 2018-02-26 | true |
| 1000 | 3 | 2018-02-25 | 2018-03-12 | true |
| 1001 | 1 | 2016-11-28 | 2017-07-30 | false |
| 1001 | 2 | 2017-07-31 | 2017-07-31 | false |
| 1001 | 3 | 2017-08-01 | 2017-08-01 | false |
该表包含大约 50k 行。查询将根据需要从前端触发,因此应该对其进行优化,以便能够尽快发回数据。任何帮助表示赞赏!
解决方案
它不会很快,因为每一行都必须与其他每一行匹配:
SELECT a.*, b.*
FROM mytable AS a
JOIN mytable AS b
ON daterange(a.valid_from, a.valid_to) && daterange(b.valid_from, b.valid_to)
WHERE (a.valid_from, a.valid_to) <= (b.valid_from, b.valid_to);
最好在表上设置一个排除约束,以防止首先添加此类数据。
推荐阅读
- python - Python赋值作为函数输入?
- c++ - OpenCL2 work_group_reduce_add 浮点输出不正确
- arrays - coffeescript:遍历数组中的对象
- android - 无法在 Android 中解析 ImageButton 的 id
- python - 如何在相关的 one_to_many 字段上正确使用 order_by 和 nulls_last?
- python - 数据框日期问题,concat 花费太多时间,图形输出错误
- python - 使用不同大小的输入迭代构建字符串
- php - 声明 PHP 类的其他方式?
- sql - 图表的自动轴
- arrays - SAS 阵列循环(执行 while 循环)