Отбор и сортировка данных в запросе с использованием приоритетов

08.01.17

Разработка - Запросы

Небольшая хитрость, позволяющая упростить сложный отбор в запросе

Имеется компания, максимально лояльно относящаяся к своим сотрудникам. Лояльность подразумевает возможность брать отпуск любой продолжительности, любое количество раз в пределах накопленного количества + авансового отпуска будущего периода + доп. дни отпуска. При всем при этом учет отпусков ведется в рабочих днях. После накопления определенного количества фактических отпускных дней они группируются по неделям, переводятся в календарные дни и "проводятся официально". Компания имеет несколько юр. лиц, и большое количество сотрудников. Учет всего, в том числе кадровый и зарплаты, ведется в 1С ERP 2 с минимальными изменениями в типовой системе учета. Для реализации возможности ведения учета отпусков была внедрена отдельная подсистема, описание которой - тема для отдельной статьи.

Имеется в этой компании некоторый портал, на котором можно посмотреть информацию по каждому из сотрудников, в том числе, находится ли он сейчас в отпуске, либо отсутствует по какой-либо другой причине. Также, на своей странице можно посмотреть все свои фактические отсутствия, накопленное количество дней отпуска, а также оставшееся количество дней дополнительного отпуска. Данные запрашиваются на лету из 1С через HTTP сервис при открытии страницы сотрудника. В качестве идентификатора сотрудника используется его логин в AD. Поле с логином сделали обязательным для заполнения в карточке физ.лица.

Люди, знакомые с особенностями ведения кадрового учета в ERP 2 и ЗУП 3.0, знают, что в указанных конфигурациях имеются справочники физ. лиц и сотрудников с соответствием один ко многим, т.е. одному физ.лицу может соответствовать несколько сотрудников. Поскольку организаций в компании несколько и сотрудников много, нередки случаи работы одного физ.лица в разных организациях, либо в одной организации на разных должностях, с разными датами приема, а, следовательно, и с разными рабочими периодами. Учет фактических отсутствий ведется в разрезе сотрудников, т.к. "официально проводить" их нужно по фактически работающим штатным единицам, но  на портале эта информация пользователю не нужна. Ему интересно знать, какой он может взять отпуск сегодня и сколько у него после этого останется накопленных дней, отсюда встает задача определения основного сотрудника, по которому будет определяться информация об отпусках.

Совместно с руководством было прниято следующее определение: основной сотрудник - это сотрудник, принятый на основное место работы, а если такого нет (т.е. на всех местах работы значится совместителем), то сотрудник с минимальной датой приема.

Как уже упоминалось, данные формируются на лету, а значит, очень важна скорость их получения, поэтому решено было получить всех основных сотрудников одним запросом, принимая в качестве параметра массив логинов. Здесь и кроется основная сложность и хитрое изощрение. Не годится простой отбор по минимальной дате приема, поскольку вводится дополнительный отбор по виду занятости. Для простоты и стройности конструкции запроса добавили приоритет  и вместо сортировки и отбора по дате приема выполняется сортировка и отбор по приоритету.

ВЫБРАТЬ РАЗРЕШЕННЫЕ
	ФизическиеЛицаКонтактнаяИнформация.Ссылка КАК ФизЛицо,
	ФизическиеЛицаКонтактнаяИнформация.Представление КАК Логин
ПОМЕСТИТЬ ВТФЛ
ИЗ
	Справочник.ФизическиеЛица.КонтактнаяИнформация КАК ФизическиеЛицаКонтактнаяИнформация
ГДЕ
	ФизическиеЛицаКонтактнаяИнформация.Вид.Наименование ПОДОБНО "%Логин%AD%"
	И ФизическиеЛицаКонтактнаяИнформация.Представление В(&Логины)

ИНДЕКСИРОВАТЬ ПО
	ФизЛицо
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ РАЗРЕШЕННЫЕ
	ТекущиеКадровыеДанныеСотрудников.Сотрудник КАК Сотрудник,
	ТекущиеКадровыеДанныеСотрудников.ДатаПриема КАК ДатаПриема,
	ТекущиеКадровыеДанныеСотрудников.ТекущийВидЗанятости КАК ТекущийВидЗанятости,
	ВТФЛ.ФизЛицо КАК ФизЛицо,
	ВТФЛ.Логин
ПОМЕСТИТЬ ВТСотрудники
ИЗ
	ВТФЛ КАК ВТФЛ
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ТекущиеКадровыеДанныеСотрудников КАК ТекущиеКадровыеДанныеСотрудников
		ПО ВТФЛ.ФизЛицо = ТекущиеКадровыеДанныеСотрудников.ФизическоеЛицо
			И (ТекущиеКадровыеДанныеСотрудников.ДатаПриема <> ДАТАВРЕМЯ(1, 1, 1))
			И (ТекущиеКадровыеДанныеСотрудников.ДатаУвольнения = ДАТАВРЕМЯ(1, 1, 1))

ИНДЕКСИРОВАТЬ ПО
	ДатаПриема,
	ФизЛицо
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ РАЗРЕШЕННЫЕ
	ВТСотрудники.ДатаПриема КАК ДатаПриема,
	КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ВТСотрудники1.ДатаПриема) КАК Порядок,
	ВТСотрудники.Логин КАК Логин,
	ВТСотрудники.Сотрудник
ПОМЕСТИТЬ ВТПриоритеты
ИЗ
	ВТСотрудники КАК ВТСотрудники
		ЛЕВОЕ СОЕДИНЕНИЕ ВТСотрудники КАК ВТСотрудники1
		ПО ВТСотрудники.ФизЛицо = ВТСотрудники1.ФизЛицо
			И ВТСотрудники.ДатаПриема >= ВТСотрудники1.ДатаПриема
			И (ВТСотрудники1.ТекущийВидЗанятости = ЗНАЧЕНИЕ(Перечисление.ВидыЗанятости.ОсновноеМестоРаботы))
ГДЕ
	ВТСотрудники.ТекущийВидЗанятости = ЗНАЧЕНИЕ(Перечисление.ВидыЗанятости.ОсновноеМестоРаботы)

СГРУППИРОВАТЬ ПО
	ВТСотрудники.Логин,
	ВТСотрудники.ДатаПриема,
	ВТСотрудники.Сотрудник

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	ВТСотрудники.ДатаПриема,
	КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ВТСотрудники1.ДатаПриема) + 100,
	ВТСотрудники.Логин,
	ВТСотрудники.Сотрудник
ИЗ
	ВТСотрудники КАК ВТСотрудники
		ЛЕВОЕ СОЕДИНЕНИЕ ВТСотрудники КАК ВТСотрудники1
		ПО ВТСотрудники.ФизЛицо = ВТСотрудники1.ФизЛицо
			И ВТСотрудники.ДатаПриема >= ВТСотрудники1.ДатаПриема
			И (ВТСотрудники1.ТекущийВидЗанятости <> ЗНАЧЕНИЕ(Перечисление.ВидыЗанятости.ОсновноеМестоРаботы))
ГДЕ
	ВТСотрудники.ТекущийВидЗанятости <> ЗНАЧЕНИЕ(Перечисление.ВидыЗанятости.ОсновноеМестоРаботы)

СГРУППИРОВАТЬ ПО
	ВТСотрудники.Логин,
	ВТСотрудники.ДатаПриема,
	ВТСотрудники.Сотрудник
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ РАЗРЕШЕННЫЕ
	ОтборФЛ.Логин КАК Логин,
	ВТПриоритеты.ДатаПриема,
	ВТПриоритеты.Сотрудник
ИЗ
	(ВЫБРАТЬ
		ВТПриоритеты.Логин КАК Логин,
		МИНИМУМ(ВТПриоритеты.Порядок) КАК Порядок
	ИЗ
		ВТПриоритеты КАК ВТПриоритеты
	
	СГРУППИРОВАТЬ ПО
		ВТПриоритеты.Логин) КАК ОтборФЛ
		ЛЕВОЕ СОЕДИНЕНИЕ ВТПриоритеты КАК ВТПриоритеты
		ПО ОтборФЛ.Логин = ВТПриоритеты.Логин
			И ОтборФЛ.Порядок = ВТПриоритеты.Порядок

Во временной таблице ВТПриоритеты вводится поле Приоритет. Помимо того, что числовой показатель приоритета увеличивается для сотрудников с большей датой приема, он также увеличивается на некоторую константу для совместителей. Это вводит некоторое ограничение на количество рабоатющих сотрудников одного физ.лица, но на практике это ограничение вряд ли будет достигнуто.

Использование такого нехитрого приема позволило достигнуть приемлемой скорости получения данных и снизить задержки при формирование ответа HTTP-сервиса.

Запросы приоритеты

См. также

Инструментарий разработчика Роли и права Запросы СКД Программист Руководитель проекта Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Платные (руб)

Инструменты для разработчиков 1С 8.3: Infostart Toolkit. Автоматизация и ускорение разработки на управляемых формах. Легкость работы с 1С.

15500 руб.

02.09.2020    174995    973    403    

931

Обновление 1С Запросы Программист Платформа 1С v8.3 1С:ERP Управление предприятием 2 Абонемент ($m)

Данный инструмент помогает анализировать доработанную конфигурацию после обновления на новый релиз и находить «битые» тексты запросов, в которых участвуют несуществующие в новом релизе метаданные.

2 стартмани

06.02.2025    1507    8    XilDen    24    

34

Запросы Программист Бесплатно (free)

Увидел cheatsheet по SQL и захотелось нарисовать подобное, но про запросы.

18.10.2024    12107    sergey279    18    

65

Запросы Программист Платформа 1С v8.3 Запросы 1C:Бухгалтерия Бесплатно (free)

Столкнулся с интересной ситуацией, которую хотел бы разобрать, ввиду её неочевидности. Речь пойдёт про использование функции запроса АВТОНОМЕРЗАПИСИ() и проблемы, которые могут возникнуть.

11.10.2024    7075    XilDen    36    

86

Запросы Программист Запросы Бесплатно (free)

Отлаживая взаимодействие с базой данных, мы регулярно сталкиваемся с зависающими или подозрительно долго выполняющимися обращениями, негативно влияющими на производительность. О том, как в PostgreSQL выявить подозрительные запросы, основываясь на доступной о них информации, расскажем в статье.

16.08.2024    9752    user1840182    5    

28

Математика и алгоритмы Запросы Программист Платформа 1С v8.3 Запросы Бесплатно (free)

Рассмотрим быстрый алгоритм поиска дублей с использованием hash функции по набору полей шапки и табличных частей.

08.07.2024    2919    ivanov660    9    

22

Запросы СКД Программист Стажер Система компоновки данных Россия Бесплатно (free)

Часто при разработке отчетов в СКД возникает ситуация, когда не совсем понятно, почему отчет выводит не те данные, которые нужны, либо не выводит вовсе. Возникает потребность увидеть конечный запрос, который формирует СКД. Как это сделать, рассмотрим в этой статье.

15.05.2024    11319    implecs    6    

48
Оставьте свое сообщение