Да задача изначальна упрощена - меня интересуют непрерывные периоды действия в днях.
Превращаем таблицу вида
в таблицу
Главная хитрость/идея: сравнить разность дат (получаем все возможные периоды для исходного множества) границ периода и количества вхождений дат (элементов множества) в этот период
Собственно текст запроса под катом
Превращаем таблицу вида
Дата | |
01.01.2015 | |
02.01.2015 | |
04.01.2015 | |
05.01.2015 | |
06.01.2015 | |
12.01.2015 |
в таблицу
ДатаНачала | ДатаОкончания | |||
01.01.2015 | 02.01.2015 | |||
04.01.2015 | 06.01.2015 | |||
12.01.2015 | 12.01.2015 |
Главная хитрость/идея: сравнить разность дат (получаем все возможные периоды для исходного множества) границ периода и количества вхождений дат (элементов множества) в этот период
КОЛИЧЕСТВО(НАЧАЛОПЕРИОДА(втДаты.Дата, ДЕНЬ)) - 1 = РАЗНОСТЬДАТ(втВариации.ДатаНачала, втВариации.ДатаОкончания, ДЕНЬ)
Собственно текст запроса под катом
ВЫБРАТЬ ДАТАВРЕМЯ(2015, 1, 1) КАК Дата ПОМЕСТИТЬ втДаты ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ ДАТАВРЕМЯ(2015, 1, 2) ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ ДАТАВРЕМЯ(2015, 1, 4) ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ ДАТАВРЕМЯ(2015, 1, 5) ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ ДАТАВРЕМЯ(2015, 1, 6) ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ ДАТАВРЕМЯ(2015, 1, 12) ; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ втДаты.Дата КАК ДатаНачала, ЕСТЬNULL(втДатыСправа.Дата, втДаты.Дата) КАК ДатаОкончания ПОМЕСТИТЬ втВариации ИЗ втДаты КАК втДаты ЛЕВОЕ СОЕДИНЕНИЕ втДаты КАК втДатыСправа ПО втДаты.Дата < втДатыСправа.Дата ; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ МИНИМУМ(НеСгруппированныеПериодыСправа.ДатаНачала) КАК ДатаНачала, НеСгруппированныеПериодыСправа.ДатаОкончания ИЗ (ВЫБРАТЬ НеСгруппированныеПериодыСправа.ДатаНачала КАК ДатаНачала, МАКСИМУМ(НеСгруппированныеПериодыСправа.ДатаОкончания) КАК ДатаОкончания ИЗ (ВЫБРАТЬ втВариации.ДатаНачала КАК ДатаНачала, втВариации.ДатаОкончания КАК ДатаОкончания ИЗ втВариации КАК втВариации ВНУТРЕННЕЕ СОЕДИНЕНИЕ втДаты КАК втДаты ПО втВариации.ДатаНачала <= втДаты.Дата И втВариации.ДатаОкончания >= втДаты.Дата СГРУППИРОВАТЬ ПО втВариации.ДатаНачала, втВариации.ДатаОкончания ИМЕЮЩИЕ КОЛИЧЕСТВО(НАЧАЛОПЕРИОДА(втДаты.Дата, ДЕНЬ)) - 1 = РАЗНОСТЬДАТ(втВариации.ДатаНачала, втВариации.ДатаОкончания, ДЕНЬ)) КАК НеСгруппированныеПериодыСправа СГРУППИРОВАТЬ ПО НеСгруппированныеПериодыСправа.ДатаНачала) КАК НеСгруппированныеПериодыСправа СГРУППИРОВАТЬ ПО НеСгруппированныеПериодыСправа.ДатаОкончания
ПО втДаты.Дата < втДатыСправа.Дата
ОтветитьУдалитьТут надо поставить <=
Иначе не будут попадать минимальные даты (например если после первого числа сразу не идёт второе).
Такая например ВТ будет неправильно обрабатываться
ВЫБРАТЬ
ДАТАВРЕМЯ(2015, 1, 1) КАК Дата
ПОМЕСТИТЬ втДаты
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ДАТАВРЕМЯ(2015, 1, 22)
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ДАТАВРЕМЯ(2015, 1, 4)
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ДАТАВРЕМЯ(2015, 1, 5)
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ДАТАВРЕМЯ(2015, 1, 6)
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ДАТАВРЕМЯ(2015, 1, 12)
;