Имя: Пароль:
1C
1С v8
Непрерывные интервалы в запросе с нюансом
, ,
0 patria0muerte
 
22.07.15
03:58
Доброго времени, коллеги!

Есть такой вопрос:

Нарисовал тут запрос, который из таблички вида:
Период    Гостиница    ФизическоеЛицо    СостояниеЗаселения
14.05.2015     Гостиница1    Иванов Иван    Заселен
21.05.2015     Гостиница1    Иванов Иван    Переселен
30.05.2015    Гостиница2    Иванов Иван    Переселен
15.06.2015     Гостиница1    Иванов Иван    Переселен
23.06.2015     Гостиница1    Иванов Иван    Выселен

Получает табличку с интервалами:
14.05.2015 - 21.05.2015 Гостиница1 Иванов Иван
21.05.2015 - 30.05.2015 Гостиница1 Иванов Иван
30.05.2015 - 15.06.2015 Гостиница2 Иванов Иван
15.06.2015 - 23.06.2015 Гостиница1 Иванов Иван

Запрос сделан по типу: v8: Подскажите запрос - непрерывные интервалы дат как собрать?

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

14.05.2015 - 30.05.2015 Гостиница1 Иванов Иван
30.05.2015 - 15.06.2015 Гостиница2 Иванов Иван
15.06.2015 - 23.06.2015 Гостиница1 Иванов Иван

?

Сам запрос, если надо, покажу, но там вроде все стандартно...
1 kosts
 
22.07.15
06:26
В данном случае можно сделать соединение с календарем.
И из дней попавшие в диапазоны найти непрерывные диапазоны (т.е. к в начальном запросе)
2 patria0muerte
 
22.07.15
07:07
(1) Немного не понял - как это реализуется?
3 1cnik2
 
22.07.15
07:14
агрегируй в минимум дату начала по всем остальным полям
4 Лодырь
 
22.07.15
07:36
(0) Предварительно по всем переселен, посмотреть предыдущую запись и в случае совпадения гостиницы выкинуть ее.
Сделать это в запросе можно.
5 patria0muerte
 
22.07.15
07:39
(3) Так она уже сгруппирована по дате начала..
Запрос следующим образом примерно выглядит:

    "ВЫБРАТЬ
    |    ВЫБОР
    |        КОГДА ГостиСрезПоследнихНачалоПериода.Период < &НачалоПериода
    |            ТОГДА &НачалоПериода
    |        ИНАЧЕ ГостиСрезПоследнихНачалоПериода.Период
    |    КОНЕЦ КАК Период,
    |    ГостиСрезПоследнихНачалоПериода.Гостиница,
    |    ГостиСрезПоследнихНачалоПериода.ФизическоеЛицо,
    |    ВЫБОР
    |        КОГДА ГостиСрезПоследнихНачалоПериода.СостояниеЗаселения = ЗНАЧЕНИЕ(Перечисление.унгСостояниеЗаселения.Переселен)
    |            ТОГДА ЗНАЧЕНИЕ(Перечисление.унгСостояниеЗаселения.Заселен)
    |        ИНАЧЕ ГостиСрезПоследнихНачалоПериода.СостояниеЗаселения
    |    КОНЕЦ КАК СостояниеЗаселения
    |ПОМЕСТИТЬ ВТДанныеПроживания
    |ИЗ
    |    РегистрСведений.унгГости.СрезПоследних(
    |            &НачалоПериода,
    |            ФизическоеЛицо В
    |                (ВЫБРАТЬ
    |                    ВТ.ФизическоеЛицо
    |                ИЗ
    |                    ВТФизическиеЛица КАК ВТ)) КАК ГостиСрезПоследнихНачалоПериода
    |ГДЕ
    |    НЕ ГостиСрезПоследнихНачалоПериода.СостояниеЗаселения = ЗНАЧЕНИЕ(Перечисление.унгСостояниеЗаселения.Выселен)
    |
    |ОБЪЕДИНИТЬ
    |
    |ВЫБРАТЬ
    |    ГостиЗаПериод.Период,
    |    ГостиЗаПериод.Гостиница,
    |    ГостиЗаПериод.ФизическоеЛицо,
    |    ГостиЗаПериод.СостояниеЗаселения
    |ИЗ
    |    РегистрСведений.унгГости КАК ГостиЗаПериод
    |ГДЕ
    |    ГостиЗаПериод.Период МЕЖДУ &НачалоПериода И &ОкончаниеПериода
    |    И ГостиЗаПериод.ФизическоеЛицо В
    |            (ВЫБРАТЬ
    |                Т.ФизическоеЛицо
    |            ИЗ
    |                ВТФизическиеЛица КАК Т)
    |;
    |
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ
    |    ВТДанныеПроживания.Период,
    |    ВТДанныеПроживания.Гостиница,
    |    ВТДанныеПроживания.ФизическоеЛицо,
    |    ВЫБОР
    |        КОГДА ВТДанныеПроживания.СостояниеЗаселения = ЗНАЧЕНИЕ(Перечисление.унгСостояниеЗаселения.Переселен)
    |            ТОГДА ЗНАЧЕНИЕ(Перечисление.унгСостояниеЗаселения.Заселен)
    |        ИНАЧЕ ВТДанныеПроживания.СостояниеЗаселения
    |    КОНЕЦ КАК СостояниеЗаселения
    |ПОМЕСТИТЬ ВТНачалаПериода
    |ИЗ
    |    ВТДанныеПроживания КАК ВТДанныеПроживания
    |ГДЕ
    |    (ВТДанныеПроживания.СостояниеЗаселения = ЗНАЧЕНИЕ(Перечисление.унгСостояниеЗаселения.Переселен)
    |            ИЛИ ВТДанныеПроживания.СостояниеЗаселения = ЗНАЧЕНИЕ(Перечисление.унгСостояниеЗаселения.Заселен))
    |;
    |
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ
    |    ВТДанныеПроживания.Период,
    |    ВТДанныеПроживания.Гостиница,
    |    ВТДанныеПроживания.ФизическоеЛицо,
    |    ВЫБОР
    |        КОГДА ВТДанныеПроживания.СостояниеЗаселения = ЗНАЧЕНИЕ(Перечисление.унгСостояниеЗаселения.Переселен)
    |            ТОГДА ЗНАЧЕНИЕ(Перечисление.унгСостояниеЗаселения.Выселен)
    |        ИНАЧЕ ВТДанныеПроживания.СостояниеЗаселения
    |    КОНЕЦ КАК СостояниеЗаселения
    |ПОМЕСТИТЬ ВТОкончанияПериода
    |ИЗ
    |    ВТДанныеПроживания КАК ВТДанныеПроживания
    |ГДЕ
    |    (ВТДанныеПроживания.СостояниеЗаселения = ЗНАЧЕНИЕ(Перечисление.унгСостояниеЗаселения.Переселен)
    |            ИЛИ ВТДанныеПроживания.СостояниеЗаселения = ЗНАЧЕНИЕ(Перечисление.унгСостояниеЗаселения.Выселен))
    |;
    |
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ
    |    ВТНачалаПериода.Период КАК НачалоПериода,
    |    ВТНачалаПериода.Гостиница,
    |    ВТНачалаПериода.ФизическоеЛицо,
    |    ЕСТЬNULL(МИНИМУМ(ВТОкончанияПериода.Период), &ОкончаниеПериода) КАК ОкончаниеПериода
    |ИЗ
    |    ВТНачалаПериода КАК ВТНачалаПериода
    |        ЛЕВОЕ СОЕДИНЕНИЕ ВТОкончанияПериода КАК ВТОкончанияПериода
    |        ПО ВТНачалаПериода.Период < ВТОкончанияПериода.Период
    |            И ВТНачалаПериода.ФизическоеЛицо = ВТОкончанияПериода.ФизическоеЛицо
    |
    |СГРУППИРОВАТЬ ПО
    |    ВТНачалаПериода.Период,
    |    ВТНачалаПериода.Гостиница,
    |    ВТНачалаПериода.ФизическоеЛицо
    |
    |УПОРЯДОЧИТЬ ПО
    |    НачалоПериода";
6 patria0muerte
 
22.07.15
07:43
(4) Сейчас попробую, кажется понял мысль...
7 1cnik2
 
22.07.15
07:50
попробуй в последнем запросе пакета выбирать из одной таблицы(где будут поля Период, Состояние, Физлицо, Гостиница)
получишь ДатаНачала, ДатаОкончания, Состояния, Физлицо, Гостиница, а потом выкинешь ненужные состояния
8 Ildarovich
 
22.07.15
13:32
Задача довольно сложная. Проблема в том, что объединить два смежных периода может быть недостаточно. Их может быть и два и три и так далее. Периоды нужно группировать. Для этого нужен инвариант - параметр интервала, который одинаков для смежных периодов. Таким инвариантом может быть разница между нарастающим итогом числа прожитых дней и календарной датой конца периода.

В общем, задача решается методом, предложенном в разделе 14 (сжатое представление последовательности дат запросом) статьи http://catalog.mista.ru/public/306536/ . Для данного случая запрос можно записать так

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    Дано.НачалоПериода,
    Дано.КонецПериода,
    Дано.Гостиница,
    Дано.ФизическоеЛицо,
    СУММА(РАЗНОСТЬДАТ(Слева.НачалоПериода, Слева.КонецПериода, ДЕНЬ) + 1) КАК Интеграл
ПОМЕСТИТЬ ДаноПлюс
ИЗ
    Дано КАК Дано
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ Дано КАК Слева
        ПО (Слева.НачалоПериода <= Дано.НачалоПериода)

СГРУППИРОВАТЬ ПО
    Дано.НачалоПериода,
    Дано.КонецПериода,
    Дано.Гостиница,
    Дано.ФизическоеЛицо
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    МИНИМУМ(Дано.НачалоПериода) КАК НачалоПериода,
    МАКСИМУМ(Дано.КонецПериода) КАК КонецПериода,
    Дано.Гостиница,
    Дано.ФизическоеЛицо
ИЗ
    ДаноПлюс КАК Дано

СГРУППИРОВАТЬ ПО
    ДОБАВИТЬКДАТЕ(Дано.КонецПериода, ДЕНЬ, -Дано.Интеграл),
    Дано.Гостиница,
    Дано.ФизическоеЛицо


Предполагается, что интервалы не пересекаются. Если они пересекаются, то можно их разбить на дни, пересечением с календарем и воспользоваться чистым методом из статьи, либо немного усложнить приведенный запрос...
9 patria0muerte
 
24.07.15
07:35
(8) Долго и много думал над этим запросом. И наконец то понял как это работает и реализовал у себя.

Огромное спасибо!
10 patria0muerte
 
24.07.15
07:37
Неплохо бы эту тему в базу знаний добавить, не? С заголовком "объединение смежных периодов в запросе"
Выдавать глобальные идеи — это удовольствие; искать сволочные маленькие ошибки — вот настоящая работа. Фредерик Брукс-младший