Всем привет, стоит задача отследить у кого пересекаются отпуска по дате внутри каждого подразделения
Есть варианты как это сделать малой кровью?
Достаточно подсветить сотрудников с пересечением.
---
```1c
    ВЫБРАТЬ
    КадроваяИсторияСотрудников.Сотрудник КАК Сотрудник,
    ФактическиеОтпуска.Регистратор КАК Регистратор,
    ВЫБОР
    КОГДА ФактическиеОтпуска.Количество ЕСТЬ NULL
    ТОГДА 0
    ИНАЧЕ ФактическиеОтпуска.Количество
    КОНЕЦ КАК КоличествоОтпуска,
    НАЧАЛОПЕРИОДА(ФактическиеОтпуска.ДатаНачала, ДЕНЬ) КАК ДатаНачала,
    КОНЕЦПЕРИОДА(ФактическиеОтпуска.ДатаОкончания, ДЕНЬ) КАК ДатаОкончания,
    КадроваяИсторияСотрудников.Подразделение КАК Подразделение
    ПОМЕСТИТЬ ТЗ1
    ИЗ
    РегистрСведений.КадроваяИсторияСотрудников КАК КадроваяИсторияСотрудников
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ФактическиеОтпуска КАК ФактическиеОтпуска
    ПО (КадроваяИсторияСотрудников.Сотрудник = ФактическиеОтпуска.Сотрудник)
    И (КадроваяИсторияСотрудников.Сотрудник = ФактическиеОтпуска.Сотрудник)
    ГДЕ
    КадроваяИсторияСотрудников.ВидСобытия <> ЗНАЧЕНИЕ(Перечисление.ВидыКадровыхСобытий.увольнение)
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    ТЗ1.Сотрудник КАК Сотрудник,
    ТЗ1.Регистратор КАК Регистратор,
    ТЗ1.КоличествоОтпуска КАК КоличествоОтпуска,
    ТЗ1.ДатаНачала КАК ДатаНачала,
    ТЗ1.ДатаОкончания КАК ДатаОкончания,
    ТЗ1.Подразделение КАК Подразделение,
    ТЗ2.Сотрудник КАК Сотрудник1
    ИЗ
    ТЗ1 КАК ТЗ1
    ЛЕВОЕ СОЕДИНЕНИЕ ТЗ1 КАК ТЗ2
    ПО (ТЗ1.Сотрудник <> ТЗ2.Сотрудник)
    И (ТЗ1.Подразделение = ТЗ2.Подразделение)
    И (ТЗ1.ДатаНачала >= ТЗ2.ДатаНачала
    И ТЗ1.ДатаНачала <= ТЗ2.ДатаОкончания
    ИЛИ ТЗ2.ДатаНачала >= ТЗ1.ДатаНачала
    И ТЗ2.ДатаНачала <= ТЗ1.ДатаОкончания)
    ГДЕ
    ТЗ2.Сотрудник <> ЗНАЧЕНИЕ(Справочник.Сотрудники.Пустаяссылка)

    СГРУППИРОВАТЬ ПО
    ТЗ1.Подразделение,
    ТЗ1.Сотрудник,
    ТЗ1.Регистратор,
    ТЗ1.КоличествоОтпуска,
    ТЗ1.ДатаНачала,
    ТЗ1.ДатаОкончания,
    ТЗ2.Сотрудник
```
---
Соединить таблицу с самой собой по Таб1.Сотрудник <> Таб2.Сотрудник.
Выбрать все поля таблицы Таб1.
Добавить группировку по всем полям Таб1, и новое поле:

```1c
    Максимум(Выбор
    Когда Таб1.ДатаНачала>=Таб2.ДатаНачала И Таб1.ДатаНачала<=Таб2.ДатаОкончания
    Тогда Истина
    Когда Таб2.ДатаНачала>=Таб1.ДатаНачала И Таб2.ДатаНачала<=Таб1.ДатаОкончания
    Тогда Истина
    Иначе Ложь Конец) Как ЕстьПересечение
```
---
Спасибо добрый человек.

 Максимум(Выбор
Когда Таб1.ДатаНачала>=Таб2.ДатаНачала И Таб1.ДатаНачала=Таб1.ДатаНачала И Таб2.ДатаНачала<=Таб1.ДатаОкончания
Тогда Истина
Иначе Ложь Конец) Как ЕстьПересечение

Вот что получилось если кому понадобиться

```1c
    ВЫБРАТЬ
    КадроваяИсторияСотрудников.Сотрудник КАК Сотрудник,
    ФактическиеОтпуска.Регистратор КАК Регистратор,
    ВЫБОР
    КОГДА ФактическиеОтпуска.Количество ЕСТЬ NULL
    ТОГДА 0
    ИНАЧЕ ФактическиеОтпуска.Количество
    КОНЕЦ КАК КоличествоОтпуска,
    НАЧАЛОПЕРИОДА(ФактическиеОтпуска.ДатаНачала, ДЕНЬ) КАК ДатаНачала,
    КОНЕЦПЕРИОДА(ФактическиеОтпуска.ДатаОкончания, ДЕНЬ) КАК ДатаОкончания,
    КадроваяИсторияСотрудников.Подразделение КАК Подразделение
    ПОМЕСТИТЬ ТЗ1
    ИЗ
    РегистрСведений.КадроваяИсторияСотрудников КАК КадроваяИсторияСотрудников
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ФактическиеОтпуска КАК ФактическиеОтпуска
    ПО КадроваяИсторияСотрудников.Сотрудник = ФактическиеОтпуска.Сотрудник
    И КадроваяИсторияСотрудников.Сотрудник = ФактическиеОтпуска.Сотрудник
    ГДЕ
    КадроваяИсторияСотрудников.ВидСобытия <> ЗНАЧЕНИЕ(Перечисление.ВидыКадровыхСобытий.увольнение)
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    КадроваяИсторияСотрудников.Сотрудник КАК Сотрудник,
    ФактическиеОтпуска.Регистратор КАК Регистратор,
    ВЫБОР
    КОГДА ФактическиеОтпуска.Количество ЕСТЬ NULL
    ТОГДА 0
    ИНАЧЕ ФактическиеОтпуска.Количество
    КОНЕЦ КАК КоличествоОтпуска,
    НАЧАЛОПЕРИОДА(ФактическиеОтпуска.ДатаНачала, ДЕНЬ) КАК ДатаНачала,
    КОНЕЦПЕРИОДА(ФактическиеОтпуска.ДатаОкончания, ДЕНЬ) КАК ДатаОкончания,
    КадроваяИсторияСотрудников.Подразделение КАК Подразделение
    ПОМЕСТИТЬ ТЗ2
    ИЗ
    РегистрСведений.КадроваяИсторияСотрудников КАК КадроваяИсторияСотрудников
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ФактическиеОтпуска КАК ФактическиеОтпуска
    ПО КадроваяИсторияСотрудников.Сотрудник = ФактическиеОтпуска.Сотрудник
    И КадроваяИсторияСотрудников.Сотрудник = ФактическиеОтпуска.Сотрудник
    ГДЕ
    КадроваяИсторияСотрудников.ВидСобытия <> ЗНАЧЕНИЕ(Перечисление.ВидыКадровыхСобытий.увольнение)
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    ТЗ1.Сотрудник КАК Сотрудник,
    ТЗ1.Регистратор КАК Регистратор,
    ТЗ1.КоличествоОтпуска КАК КоличествоОтпуска,
    ТЗ1.ДатаНачала КАК ДатаНачала,
    ТЗ1.ДатаОкончания КАК ДатаОкончания,
    ТЗ1.Подразделение КАК Подразделение,
    МАКСИМУМ(ВЫБОР
    КОГДА ТЗ1.ДатаНачала >= ТЗ2.ДатаНачала
    И ТЗ1.ДатаНачала <= ТЗ2.ДатаОкончания
    ТОГДА ИСТИНА
    КОГДА ТЗ2.ДатаНачала >= ТЗ1.ДатаНачала
    И ТЗ2.ДатаНачала <= ТЗ1.ДатаОкончания
    ТОГДА ИСТИНА
    ИНАЧЕ ЛОЖЬ
    КОНЕЦ) КАК Поле1
    ИЗ
    ТЗ1 КАК ТЗ1
    ПОЛНОЕ СОЕДИНЕНИЕ ТЗ2 КАК ТЗ2
    ПО ТЗ1.Сотрудник <> ТЗ2.Сотрудник
    И ТЗ1.Подразделение = ТЗ2.Подразделение

    СГРУППИРОВАТЬ ПО
    ТЗ1.Подразделение,
    ТЗ1.Сотрудник,
    ТЗ1.Регистратор,
    ТЗ1.КоличествоОтпуска,
    ТЗ1.ДатаНачала,
    ТЗ1.ДатаОкончания
```

но есть НО, т.к. пересекли обе таблицы то записи двоятся по каждому сотруднику одна запись где он в Таб1 а другая в Таб2 и потом наоборот:

Иванов пересекается с Петровым
Петров пересекается с Ивановым
---
т.к. пересекли обе таблицы то записи двоятся по каждому сотруднику
А чего они двоятся, вы же их сгруппировали?

По поводу запроса - не надо 2 раза получать данные, они у вас уже есть в ТЗ1, просто соединитесь с ней же самой.

```1c
    ВЫБРАТЬ
    КадроваяИсторияСотрудников.Сотрудник КАК Сотрудник,
    ФактическиеОтпуска.Регистратор КАК Регистратор,
    ВЫБОР
    КОГДА ФактическиеОтпуска.Количество ЕСТЬ NULL
    ТОГДА 0
    ИНАЧЕ ФактическиеОтпуска.Количество
    КОНЕЦ КАК КоличествоОтпуска,
    НАЧАЛОПЕРИОДА(ФактическиеОтпуска.ДатаНачала, ДЕНЬ) КАК ДатаНачала,
    КОНЕЦПЕРИОДА(ФактическиеОтпуска.ДатаОкончания, ДЕНЬ) КАК ДатаОкончания,
    КадроваяИсторияСотрудников.Подразделение КАК Подразделение
    ПОМЕСТИТЬ ТЗ1
    ИЗ
    РегистрСведений.КадроваяИсторияСотрудников КАК КадроваяИсторияСотрудников
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ФактическиеОтпуска КАК ФактическиеОтпуска
    ПО КадроваяИсторияСотрудников.Сотрудник = ФактическиеОтпуска.Сотрудник
    И КадроваяИсторияСотрудников.Сотрудник = ФактическиеОтпуска.Сотрудник
    ГДЕ
    КадроваяИсторияСотрудников.ВидСобытия <> ЗНАЧЕНИЕ(Перечисление.ВидыКадровыхСобытий.увольнение)
    ;

    ////////////////////////////////////////////////////////////­­////////////////////
    ВЫБРАТЬ
    ТЗ1.Сотрудник КАК Сотрудник,
    ТЗ1.Регистратор КАК Регистратор,
    ТЗ1.КоличествоОтпуска КАК КоличествоОтпуска,
    ТЗ1.ДатаНачала КАК ДатаНачала,
    ТЗ1.ДатаОкончания КАК ДатаОкончания,
    ТЗ1.Подразделение КАК Подразделение,
    МАКСИМУМ(ВЫБОР
    КОГДА ТЗ1.ДатаНачала >= ТЗ2.ДатаНачала
    И ТЗ1.ДатаНачала <= ТЗ2.ДатаОкончания
    ТОГДА ИСТИНА
    КОГДА ТЗ2.ДатаНачала >= ТЗ1.ДатаНачала
    И ТЗ2.ДатаНачала <= ТЗ1.ДатаОкончания
    ТОГДА ИСТИНА
    ИНАЧЕ ЛОЖЬ
    КОНЕЦ) КАК Поле1
    ИЗ
    ТЗ1 КАК ТЗ1
    ЛЕВОЕ СОЕДИНЕНИЕ ТЗ1 КАК ТЗ2
    ПО ТЗ1.Сотрудник <> ТЗ2.Сотрудник
    И ТЗ1.Подразделение = ТЗ2.Подразделение

    СГРУППИРОВАТЬ ПО
    ТЗ1.Подразделение,
    ТЗ1.Сотрудник,
    ТЗ1.Регистратор,
    ТЗ1.КоличествоОтпуска,
    ТЗ1.ДатаНачала,
    ТЗ1.ДатаОкончания
```

П.С. Также кажется, что достаточно будет ЛЕВОГО соединения, Полное тут не нужно.
---
А чего они двоятся, вы же их сгруппировали?

Если выводить данные только из одной таблицы ТЗ1 то тогда мы получим у кого двоятся отпуска и запись уникальная в логическом смысле...но не увидим с кем двоятся. Поэтому если добавить вторую таблицу с кем двоится первая таблица то тогда получается полное пересечение и задвоение.

На счет отредактированного запроса - спасибо.
---
но не увидим с кем двоятся.
Это совсем другая задача))

Если надо это решить именно в запросе, то надо не отдельное поле делать с признаком, а соединяться по датам

```1c
    ЛЕВОЕ СОЕДИНЕНИЕ ТЗ1 КАК ТЗ2
    ПО ТЗ1.Сотрудник <> ТЗ2.Сотрудник
    И ТЗ1.Подразделение = ТЗ2.Подразделение
    И ((ТЗ1.ДатаНачала >= ТЗ2.ДатаНачала
    И ТЗ1.ДатаНачала <= ТЗ2.ДатаОкончания)
    ИЛИ (ТЗ2.ДатаНачала >= ТЗ1.ДатаНачала)
    И (ТЗ2.ДатаНачала <= ТЗ1.ДатаОкончания))
```

И в выборку добавить поля из ТЗ2, например, ТЗ2.Сотрудник - тогда для каждой записи будет видно с кем пересекается.
Соответственно, если будет несколько пересечений, то будет несколько записей.
---
я видимо что не вкуриваю соединении
Ведь в левом соединении мы дополним записи левой таблицы записями правой таблицы, но т.к. у нас обе таблицы одинаковые то они пересекутся как по полному соединению один к одному и получается что
В левой таблице Иванов пересечется по отпуску с Петровым но Петров то же есть в первой таблице и он пересечется со второй таблицей по Иванову
и как результат две записи
Иванов -Петров
Петров - Иванов
---
и как результат две записи
Иванов -Петров
Петров - Иванов

Ну да, так и будет. У них же у обоих отпуска пересекаются.

Ведь так и стоит задача - найти сотрудников отдела у которых отпуска пересекаются.

А какой результат нужно получить то?

Если бы у вас была управляемая форма с таблицей значений то при активизации строки можно было бы выделить цветом строки, которые пересекаются.
---
Получается что он мало чем отличается от первого запроса где нет условий в соединении по датам. Задача решена в общем. Спасибо за помощь.
---
```1c
    ВЫБРАТЬ
    КадроваяИсторияСотрудников.Сотрудник КАК Сотрудник,
    ФактическиеОтпуска.Регистратор КАК Регистратор,
    ВЫБОР
    КОГДА ФактическиеОтпуска.Количество ЕСТЬ NULL
    ТОГДА 0
    ИНАЧЕ ФактическиеОтпуска.Количество
    КОНЕЦ КАК КоличествоОтпуска,
    НАЧАЛОПЕРИОДА(ФактическиеОтпуска.ДатаНачала, ДЕНЬ) КАК ДатаНачала,
    КОНЕЦПЕРИОДА(ФактическиеОтпуска.ДатаОкончания, ДЕНЬ) КАК ДатаОкончания,
    КадроваяИсторияСотрудников.Подразделение КАК Подразделение
    ПОМЕСТИТЬ ТЗ1
    ИЗ
    РегистрСведений.КадроваяИсторияСотрудников КАК КадроваяИсторияСотрудников
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ФактическиеОтпуска КАК ФактическиеОтпуска
    ПО (КадроваяИсторияСотрудников.Сотрудник = ФактическиеОтпуска.Сотрудник)
    И (КадроваяИсторияСотрудников.Сотрудник = ФактическиеОтпуска.Сотрудник)
    ГДЕ
    КадроваяИсторияСотрудников.ВидСобытия <> ЗНАЧЕНИЕ(Перечисление.ВидыКадровыхСобытий.увольнение)
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    ТЗ1.Сотрудник КАК Сотрудник,
    ТЗ1.Регистратор КАК Регистратор,
    ТЗ1.КоличествоОтпуска КАК КоличествоОтпуска,
    ТЗ1.ДатаНачала КАК ДатаНачала,
    ТЗ1.ДатаОкончания КАК ДатаОкончания,
    ТЗ1.Подразделение КАК Подразделение,
    ТЗ2.Сотрудник КАК Сотрудник1
    ИЗ
    ТЗ1 КАК ТЗ1
    ЛЕВОЕ СОЕДИНЕНИЕ ТЗ1 КАК ТЗ2
    ПО (ТЗ1.Сотрудник <> ТЗ2.Сотрудник)
    И (ТЗ1.Подразделение = ТЗ2.Подразделение)
    И (ТЗ1.ДатаНачала >= ТЗ2.ДатаНачала
    И ТЗ1.ДатаНачала <= ТЗ2.ДатаОкончания
    ИЛИ ТЗ2.ДатаНачала >= ТЗ1.ДатаНачала
    И ТЗ2.ДатаНачала <= ТЗ1.ДатаОкончания)
    ГДЕ
    ТЗ2.Сотрудник <> ЗНАЧЕНИЕ(Справочник.Сотрудники.Пустаяссылка)

    СГРУППИРОВАТЬ ПО
    ТЗ1.Подразделение,
    ТЗ1.Сотрудник,
    ТЗ1.Регистратор,
    ТЗ1.КоличествоОтпуска,
    ТЗ1.ДатаНачала,
    ТЗ1.ДатаОкончания,
    ТЗ2.Сотрудник
```