Самый быстрый способ разделить перекрывающиеся диапазоны дат

У меня есть данные диапазона дат в таблице базы данных SQL, в которой есть эти три (только релевантные) столбцы:

  • ID (int identity)
  • RangeFrom (только дата)
  • RangeTo (только дата)

Для любого заданного диапазона дат может быть произвольное количество записей, которые могут перекрываться (полностью или частично ).

Условия

  1. Каждая запись с более высоким ID (более новая запись) имеет приоритет над более старыми записями, которые могут перекрываться (полностью или частично)
  2. Диапазоны длиной не менее 1 дня ( RangeFrom и RangeTo отличаются на один день)

Таким образом, для заданного диапазона дат (не более, чем, например, 5 лет) я должен

  1. получить все записи диапазона, которые попадают в этот диапазон. (полностью или частично)
  2. разделить эти перекрытия на неперекрывающиеся диапазоны
  3. вернуть эти новые неперекрывающиеся диапазоны

Мое мнение

Поскольку с этими диапазонами связано много сложных данных (много присоединяется и т.д. Это дало мне гораздо больше гибкости, а также скорости с точки зрения разработки и выполнения.

Если вы считаете, что с этим лучше справиться в БД, дайте мне знать.

Вопрос

Я хотел бы написать максимально быстрый и, если возможно, ресурсосберегающий алгоритм преобразования. Поскольку я получаю много этих записей, и они связаны с разными пользователями, мне приходится запускать этот алгоритм для каждого пользователя и его набора данных перекрывающихся диапазонов.

Каким будет наиболее эффективный (быстрый и не требующий ресурсов) способ разделения этих перекрывающихся диапазонов?

Пример данных

У меня есть записи с ID = 1 до ID = 5 , которые визуально перекрываются таким образом (даты на самом деле не имеют значения, я могу лучше показать эти совпадения таким образом):

       6666666666666
                44444444444444444444444444         5555555555
          2222222222222            333333333333333333333            7777777
11111111111111111111111111111111111111111111111111111111111111111111

Результат должен выглядеть так:

111111166666666666664444444444444444444444333333333555555555511111117777777

Результат на самом деле выглядит так, как если бы мы смотрели на эти перекрытия сверху, а затем получаем идентификаторы, которые мы видим из этого вида сверху вниз.

Результат фактически будет преобразован в новые записи диапазона, поэтому старые идентификаторы станут неактуальными. Но их значения RangeFrom и RangeTo (вместе со всеми связанными данными) будут использоваться:

111111122222222222223333333333333333333333444444444555555555566666667777777

Это, конечно, просто пример перекрывающихся диапазонов. Это может быть что угодно, от 0 до X для любого заданного диапазона дат. И, как мы видим, диапазон ID = 2 был полностью перезаписан на 4 и 6, поэтому он полностью устарел.

9
задан Robert Koritnik 19 April 2011 в 07:09
поделиться