我在 SQL DB 表中有日期范围数据,其中包含这三个(仅相关)列:
ID
(整数身份)RangeFrom
(仅限日期)RangeTo
(仅限日期)
对于任何给定的日期范围,可能有任意数量的记录可能重叠(完全或部分)。
条件
- 具有较高
ID
(较新记录)的每个记录优先于可能重叠(全部或部分)的较旧记录 - 范围至少为 1 天(
RangeFrom
相差RangeTo
一天)
因此,对于给定的日期范围(不超过 5 年),我必须
- 获取所有属于该范围的范围记录(全部或部分)
- 将这些重叠分割成不重叠的范围
- 返回这些新的非重叠范围
我的看法
由于有很多与这些范围相关的复杂数据(大量连接等),并且由于处理器 + 内存能力比 SQL DB 引擎效率更高,我决定将重叠数据从 DB 加载到我的数据层并进行范围切割/在内存中分裂。这在开发和执行方面给了我更多的灵活性和速度。
如果您认为这应该在 DB 中更好地处理,请告诉我。
问题
我想写出最快的,如果可能的话,也是资源非饥饿的转换算法。由于我得到了很多这些记录并且它们与不同的用户有关,我必须为每个用户及其重叠范围数据集运行这个算法。
拆分这些重叠范围的最有效(快速且不占用资源)的方法是什么?
示例数据
我有ID=1
以ID=5
这种方式在视觉上重叠的记录(日期实际上是无关紧要的,我可以更好地显示这些重叠):
6666666666666
44444444444444444444444444 5555555555
2222222222222 333333333333333333333 7777777
11111111111111111111111111111111111111111111111111111111111111111111
结果应如下所示:
111111166666666666664444444444444444444444333333333555555555511111117777777
结果实际上看起来好像我们将从顶部查看这些重叠,然后获取我们从该自上而下视图中看到的 ID。
结果实际上将转换为新的范围记录,因此旧 ID 变得无关紧要。但是将使用它们的RangeFrom
和RangeTo
值(以及所有相关数据):
111111122222222222223333333333333333333333444444444555555555566666667777777
这当然只是重叠范围的一个例子。对于任何给定的日期范围,它可以是从 0 条记录到 X 的任何东西。正如我们所见,范围 ID=2 完全被 4 和 6 覆盖,因此它完全过时了。