Проверьте, попадает ли диапазон дат в WW - PullRequest
0 голосов
/ 11 июля 2019

У меня есть вопрос о сравнении диапазонов дат.У меня есть таблица с журналом состояния машины.Состояние может быть 0 или 1. Кроме того, у меня есть дата, когда началось изменение состояния машины и когда оно закончилось

START_DATE | END_DATE | STATE

Например:

     START_DATE     |       END_DATE        | STATE
2019-05-28 07:12:43   2019-05-29 09:12:43       1
2019-05-29 09:12:43   2019-06-01 08:12:43       0
2019-06-11 10:12:43   2019-06-12 16:12:43       1
2019-06-12 16:12:43   2019-06-12 17:12:43       0

Я хочу сделатьотчет, в котором повторяются все WW (рабочая неделя) и проверяется, какое среднее состояние было на этом WW.

Моя проблема в том, что изменение состояния могло произойти на WW22 и закончиться на WW24, поэтому, когда я получаю GROUP BY WW, я получаюнет значений на WW23, потому что на WW23 не было ни начального, ни конечного состояния.Но на WW23 эта машина находилась в состоянии 0, потому что она начиналась на WW22 и заканчивалась на WW24, но все это время состояние было 0.

Похоже, я не могу использовать GROUP BY WW для ее решения.Возможно, мне придется проверить START_DATE и END_DATE в тех случаях, когда на WW23 нет записей.добавить что-то вроде:

CASE WHEN WW BETWEEN START_DATE AND END_DATE THEN...

Но я не уверен, как зациклить на WW без использования GROUP BY.

Я использую SQL ORACLE

Спасибо.

1 Ответ

1 голос
/ 11 июля 2019

Надеюсь, я правильно понял.Было бы хорошо, если бы Вы показали нам свой запрос и сообщили, как вы рассчитываете среднее состояние и откуда эти недели.В любом случае, вот запрос, который генерирует все недели для 2019 года и объединяет с вашим log.

select to_char(wsd, 'iw') week, wsd, start_date, end_date, state
  from (
    select trunc(date '2019-01-01', 'iw') + level * 7 - 7 wsd
      from dual 
      connect by trunc(date '2019-01-01', 'iw') + level * 7 <= date '2020-01-01')
  left join log on wsd < end_date and start_date < wsd + 7

Интересен этот диапазон:

week  week_start_date  log_start            log_end              state
21    2019-05-20
22    2019-05-27       2019-05-28 07:12:43  2019-05-29 09:12:43  1
22    2019-05-27       2019-05-29 09:12:43  2019-06-01 08:12:43  0
23    2019-06-03
24    2019-06-10       2019-06-11 10:12:43  2019-06-12 16:12:43  1
24    2019-06-10       2019-06-12 16:12:43  2019-06-12 17:12:43  0
25    2019-06-17

Я не знаю, как вы подсчитываете среднее состояние для недель 22 и 24. Может быть, это средневзвешенное значение за вычтенное время, может быть как-тоДругой.Но это не важно, теперь у вас есть строка на 23-ю неделю с пропуском state.Если это означает, что предыдущее значение действительно для этой недели, используйте:

nvl(state, lag(state) over (order by wsd))

или

coalesce(state, lag(state) over (order by wsd), 0)

, если вы хотите 0 в качестве значения по умолчанию, когда мы также пропускаем предыдущую неделю (недели),Если не хватает двух недель, добавьте ignore nulls к lag.

Затем вы можете сгруппировать данные по неделям и посчитать средние значения.

Демо-версия dbfiddle

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