Пересечение дат в СКД

1. Ujine1313 9 22.11.21 17:05 Сейчас в теме
Всем привет, стоит задача отследить у кого пересекаются отпуска по дате внутри каждого подразделения
Есть варианты как это сделать малой кровью?
Достаточно подсветить сотрудников с пересечением.
Прикрепленные файлы:
По теме из базы знаний
Вознаграждение за ответ
Показать полностью
Найденные решения
10. Ujine1313 9 23.11.21 19:07 Сейчас в теме
ВЫБРАТЬ
	КадроваяИсторияСотрудников.Сотрудник КАК Сотрудник,
	ФактическиеОтпуска.Регистратор КАК Регистратор,
	ВЫБОР
		КОГДА ФактическиеОтпуска.Количество ЕСТЬ 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.Сотрудник
Показать
Остальные ответы
Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
2. Sashares 34 22.11.21 18:12 Сейчас в теме
(1)Соединить таблицу с самой собой по Таб1.Сотрудник <> Таб2.Сотрудник.
Выбрать все поля таблицы Таб1.
Добавить группировку по всем полям Таб1, и новое поле:
Максимум(Выбор 
Когда Таб1.ДатаНачала>=Таб2.ДатаНачала И Таб1.ДатаНачала<=Таб2.ДатаОкончания 
Тогда Истина
Когда Таб2.ДатаНачала>=Таб1.ДатаНачала И Таб2.ДатаНачала<=Таб1.ДатаОкончания 
Тогда Истина 
Иначе Ложь Конец) Как ЕстьПересечение
Ujine1313; +1 Ответить
3. Ujine1313 9 23.11.21 13:36 Сейчас в теме
(2)
Спасибо добрый человек.

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


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

ВЫБРАТЬ
	КадроваяИсторияСотрудников.Сотрудник КАК Сотрудник,
	ФактическиеОтпуска.Регистратор КАК Регистратор,
	ВЫБОР
		КОГДА ФактическиеОтпуска.Количество ЕСТЬ 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 и потом наоборот:

Иванов пересекается с Петровым
Петров пересекается с Ивановым
4. Sashares 34 23.11.21 13:41 Сейчас в теме
(3)
т.к. пересекли обе таблицы то записи двоятся по каждому сотруднику

А чего они двоятся, вы же их сгруппировали?

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

ВЫБРАТЬ
    КадроваяИсторияСотрудников.Сотрудник КАК Сотрудник,
    ФактическиеОтпуска.Регистратор КАК Регистратор,
    ВЫБОР
        КОГДА ФактическиеОтпуска.Количество ЕСТЬ 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.ДатаОкончания
Показать


П.С. Также кажется, что достаточно будет ЛЕВОГО соединения, Полное тут не нужно.
5. Ujine1313 9 23.11.21 15:23 Сейчас в теме
(4)
А чего они двоятся, вы же их сгруппировали?


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

На счет отредактированного запроса - спасибо.
Прикрепленные файлы:
6. Sashares 34 23.11.21 15:29 Сейчас в теме
(5)
но не увидим с кем двоятся.

Это совсем другая задача))

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

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


И в выборку добавить поля из ТЗ2, например, ТЗ2.Сотрудник - тогда для каждой записи будет видно с кем пересекается.
Соответственно, если будет несколько пересечений, то будет несколько записей.
7. Ujine1313 9 23.11.21 17:43 Сейчас в теме
я видимо что не вкуриваю соединении
Ведь в левом соединении мы дополним записи левой таблицы записями правой таблицы, но т.к. у нас обе таблицы одинаковые то они пересекутся как по полному соединению один к одному и получается что
В левой таблице Иванов пересечется по отпуску с Петровым но Петров то же есть в первой таблице и он пересечется со второй таблицей по Иванову
и как результат две записи
Иванов -Петров
Петров - Иванов
8. Sashares 34 23.11.21 18:03 Сейчас в теме +1 $m
(7)
и как результат две записи
Иванов -Петров
Петров - Иванов


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

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

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

Если бы у вас была управляемая форма с таблицей значений то при активизации строки можно было бы выделить цветом строки, которые пересекаются.
9. Ujine1313 9 23.11.21 19:04 Сейчас в теме
Получается что он мало чем отличается от первого запроса где нет условий в соединении по датам. Задача решена в общем. Спасибо за помощь.
10. Ujine1313 9 23.11.21 19:07 Сейчас в теме
ВЫБРАТЬ
	КадроваяИсторияСотрудников.Сотрудник КАК Сотрудник,
	ФактическиеОтпуска.Регистратор КАК Регистратор,
	ВЫБОР
		КОГДА ФактическиеОтпуска.Количество ЕСТЬ 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.Сотрудник
Показать
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот