Можно ли запросом "свернуть" таблицу периодов? #700829


#0 by nvs
Есть таблица из двух колонок: дата начала, дата окончания. Надо свернуть таблицу так, чтобы в итоге остались непересекаемые между собой периоды. Например: периоды (01.01.2012 - 31.12.2012) и (01.01.2013 - 31.12.2013) должны сложиться в (01.01.2012 - 31.12.2013) периоды (01.01.2012 - 31.08.2012) и (01.07.2012 - 31.12.2012) должны свернуться в (01.01.2012 - 31.12.2012) Можно это сделать одним запросом?
#1 by butterbean
в твоем примере в итоге должен остаться только период (01.01.2012 - 31.12.2013) , правильно??
#2 by shuhard
[Можно это сделать одним запросом?] в общем случае - нет
#3 by catena
А если периоды (01.01.2012 - 30.11.2012) и (01.01.2013 - 31.12.2013) ?
#4 by mikecool
началопериода(год) и складывай
#5 by nvs
- да в итоге один период останется, но в общем случае может быть множество непересекаемых периодов - в это м случае в итоговой таблице останется два периода, поскольку они не пересекаются и не соприкасаются - тоже так кажется
#6 by catena
Дайте примеров. ВЫБРАТЬ Из тз КАК тз     Левое Соединение тз как тз2 по (тз.Б >= ДобавитьКДате(тз2.А,День,-1) и тз.Б<=тз2.Б) Сгруппировать по тз.А; //////////////////////////////////////////////////////////////////////////////// Выбрать тз.А,тз.Б из тзОбъединенныеОтрезки как тз Левое Соединение тзОбъединенныеОтрезки как тз2 по (тз2.А<тз.А и тз.Б между тз2.А и тз2.Б)или(тз2.Б>тз.Б и тз.А между тз2.А и тз2.Б) Где тз2.А есть NULL
#7 by grigo
Запросом в общем случае не решается.
#8 by nvs
тут есть такая проблема: после первого выполнения данного запроса появится новая таблица периодов, которые также могут свернуться. тут как-то булеву матрицу пересечений периодов надо строить или что-то в этом духе...
#9 by George Wheels
Сделай рекурсивный вызов или запрос в цикле. Сравнивай количество строк в ТЗ до обработки запросом и после. Если количество строк одинаково, то все периоды свернулись.
#10 by catena
Не поняла, какая новая таблица? Я отбираю периоды, которые не вложены ни в один другой. Может где накосячила, дайте пример с недосвернутыми оборотами.
#11 by kumena
>>> периоды (01.01.2012 - 31.12.2012) и (01.01.2013 - 31.12.2013) должны сложиться в (01.01.2012 - 31.12.2013) я такое делал запросом, результат можно посмотреть здесь >>> периоды (01.01.2012 - 31.08.2012) и (01.07.2012 - 31.12.2012) должны свернуться в (01.01.2012 - 31.12.2012) думаю что тоже можно, но на халяву думать не интересно.
#12 by nvs
ваш алгоритм попробуйте на данных:
#13 by catena
Ага. Идея такая: тзТочки - собираем вообще все точки из наших периодов. тзОтрезкиПоПорядку - это все отрезки между нашими точками. тзНевходящиеОтрезки - находим среди отрезков по порядку те, которые не входят ни в один период. тзОбъединенныеОтрезки - вообще все варианты отрезков из наших точек, исключая отрезки, которые содержат никуда невходящие периоды. Итог - из всех отрезков выбираем самые большие, т.е. те, которые не входят ни в один другой отрезок.
#14 by nvs
ага вроде рабочий вариант, сейчас еще по полочкам у себя в голове разложу запрос. Большое спасибо!
#15 by kosts
1. Создаем служебную ВТ с календарем. 2. Соединяем свои периоды с календарем. Для дней которые попали в период ставим в новом поле - 1, для тех дней, которые  не попали - 0. Имеем календарь дней, назовем График. Например, получим: ДатаКалендаря, Поле1 3. Теперь соединяя и группируя Календарю из и График из , условие соединения: к дню из календаря присоединим СЛЕДУЮЩИЙ день из Графика. Этим мы найдем граничные дни. Например должны получить: 4. Теперь соединяя саму с собой таблицу , группируя и минимизируя получим ДатаС, ДатаПо, Поле1 Может в и такой же принцип, но анализировать лень...
#16 by catena
Не, вариант с подсчетом попадающих точек я не стала доделывать еще когда объем пересекающихся кубов считали. Не помню почему)
#17 by kosts
Другой вариант, найти периоды пустот Затем из общего периода убрать пустоты, получим нужные итоговые периоды. (уже лень опять стало делать).
#18 by kosts
+ Т.е. что бы получить итоговые периоды нужно добавить 2 искусственных периода сверху и снизу и сделать совершенные аналогичные действия как в .
#19 by nvs
Вот чего я накопал: Построил матрицу связей периодов (по вертикали периоды, по горизонтали тоже, элемент матрицы = 1 если периоды граничат или пересекаются, иначе 0). Далее необходимо построить матрицу достижимости Элементы матрицы достижимости по Алгоритму Флойда — Уоршелла for k = 1 to n   for i = 1 to n     for j = 1 to n Далее клеим по этой матрице наши периоды и выбираем минимумы дат начала и максимум дат окончания только вот этот цикл в запросом выполнить надо
#20 by nvs
и еще вариант: ОБЪЕДИНИТЬ ВЫБРАТЬ 1 ОБЪЕДИНИТЬ ВЫБРАТЬ 2 ОБЪЕДИНИТЬ ВЫБРАТЬ 3 ОБЪЕДИНИТЬ ВЫБРАТЬ 4 ОБЪЕДИНИТЬ ВЫБРАТЬ 5 ОБЪЕДИНИТЬ ВЫБРАТЬ 6 ОБЪЕДИНИТЬ ВЫБРАТЬ 7 ОБЪЕДИНИТЬ ВЫБРАТЬ 8 ОБЪЕДИНИТЬ ВЫБРАТЬ 9 ; ИЗ Т КАК Т, СписокЦифр КАК ЦифрыПорядка3, СписокЦифр КАК ЦифрыПорядка2, СписокЦифр КАК ЦифрыПорядка1, СписокЦифр КАК ЦифрыПорядка0 ГДЕ ИЗ Т2 КАК Т2_11 ГДЕ Т2_21.Дата ЕСТЬ NULL ; НачалаПериодов.Дата, ИЗ НачалаПериодов КАК НачалаПериодов ИЗ Т2 КАК Т2_11 ГДЕ Т2_21.Дата ЕСТЬ NULL ; КонцыПериодов.Дата, ИЗ КонцыПериодов КАК КонцыПериодов НачалаПериодовСНомеромСтроки.Дата КАК НачалоПериода, КонцыПериодовСНомеромСтроки.Дата КАК КонецПериода ИЗ НачалаПериодовСНомеромСтроки КАК НачалаПериодовСНомеромСтроки ВНУТРЕННЕЕ СОЕДИНЕНИЕ КонцыПериодовСНомеромСтроки КАК КонцыПериодовСНомеромСтроки ПО НачалаПериодовСНомеромСтроки.НомерСтроки = КонцыПериодовСНомеромСтроки.НомерСтроки
#21 by catena
Вариант будет выглядеть так:
#22 by APXi
Интересно как потом такие запросы сопровождать, особенно если нет описания.
Тэги: 1С 8
Ответить:
Комментарии доступны только авторизированным пользователям

В этой группе 1С