Пересечение диапазона дат в SQL - PullRequest
4 голосов
/ 05 мая 2010

У меня есть таблица, в которой каждая строка имеет дату и время начала и окончания. Это могут быть произвольно короткие или длинные промежутки.

Я хочу запросить суммарную продолжительность пересечения всех строк с двумя датами начала и окончания.

Как вы можете сделать это в MySQL?

Или вам нужно выбрать строки, которые пересекают время начала и окончания запроса, затем рассчитать фактическое перекрытие каждой строки и суммировать его на стороне клиента?


Чтобы привести пример, используйте миллисекунды, чтобы прояснить ситуацию:

Некоторые строки:

ROW  START  STOP
1    1010   1240
2     950   1040
3    1120   1121

И мы хотим знать сумму времени, когда эти строки были между 1030 и 1100.

Позволяет вычислить перекрытие каждой строки:

ROW  INTERSECTION
1    70
2    10
3     0

Таким образом, сумма в этом примере равна 80.

Ответы [ 4 ]

5 голосов
/ 05 мая 2010

Если ваш пример должен был сказать 70 в первом ряду, то

принимая в качестве параметров условия @range_start и @range_end:

SELECT SUM( LEAST(@range_end, stop) - GREATEST(@range_start, start) )
FROM Table
WHERE @range_start < stop AND @range_end > start

с использованием наибольших / наименьших и функций даты вы сможете получить то, что вам нужно, непосредственно работая с типом даты.

1 голос
/ 05 мая 2010

Есть довольно интересное решение, если вы знаете максимальное время, которое у вас когда-либо будет. Создайте таблицу со всеми числами в ней от одного до вашего максимального времени.

millisecond
-----------
1
2
3
...
1240

Назовите это time_dimension (этот метод часто используется в многомерном моделировании в хранилищах данных.)

Тогда это:

SELECT 
  COUNT(*) 
FROM 
  your_data 
    INNER JOIN time_dimension ON time_dimension.millisecond BETWEEN your_data.start AND your_data.stop
WHERE 
  time_dimension.millisecond BETWEEN 1030 AND 1100

... даст вам общее количество миллисекунд времени работы между 1030 и 1100.

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

Это часто используется в хранилищах данных, как я уже сказал; он хорошо подходит для некоторых видов проблем - например, я использовал его для систем страхования, где было необходимо общее количество дней между двумя датами, и где общий диапазон дат данных было легко оценить (из самая ранняя дата рождения клиента - дата через пару лет в будущем, после даты окончания любой политики, которая была продана.)

Может не сработать для вас, но я решил, что стоит поделиться как интересная техника!

1 голос
/ 05 мая 2010

Боюсь, вам не повезло.

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

Требуемый оператор агрегирования не является опцией, поскольку в SQL нет типа данных, с которым он должен работать (этот тип является интервальным, как описано в разделе «Временные данные и реляционная модель»).

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

Или я неправильно понял ваш вопрос.

0 голосов
/ 05 мая 2010

После того, как вы добавили пример, становится ясно, что я действительно неправильно понял ваш вопрос.

Вы не "кумулятивно пересекающиеся строки".

Шаги, которые приведут вас к решению:

пересекают начальную и конечную точки каждой строки с заданными начальной и конечной точками. Это должно быть выполнимо, используя выражения CASE или что-то в этом роде, что-то в стиле:

SELECT (CASE startdate = Givenstartdate: startdate) в качестве retainedstartdate ((аналогично для enddate) в качестве retainedenddate FROM ... Обслуживает пустые значения и такие вещи, как необходимо.

С помощью retainedstartdate и retainedenddate используйте функцию date, чтобы вычислить длину оставшегося интервала (который является перекрытием вашей строки с данным отрезком времени).

ВЫБЕРИТЕ СУММУ () из них.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...