При формировании отчетов или выборок по кадровым данным часто возникает задача: у одного сотрудника в системе может быть зарегистрировано несколько записей об образовании (например, среднее и высшее). Если просто соединить таблицы, мы получим дублирование строк, что приводит к некорректным результатам. Разберем, как грамотно настроить запрос, чтобы выводить только наиболее «важное» образование в соответствии с установленным приоритетом.
Самым эффективным способом решения данной задачи является назначение числового веса или ранга каждому виду образования. Вместо того чтобы пытаться выстроить сложную логику «если нет этого, то то» с помощью множественных операторов ПОДОБНО, мы предложим системе четкий порядок приоритетов.
Рассмотрим структуру приоритетов:
Когда у нас есть числовой ранг, задача сводится к поиску минимального значения для каждого физического лица. Тот вид образования, который имеет минимальный ранг, и является для нас приоритетным.
Чтобы реализовать этот подход в консоли запросов, мы можем использовать конструкцию ВЫБОР для присвоения веса, а затем сгруппировать данные. Рассмотрим, как это выглядит на практике:
ВЫБРАТЬ
Образование.Владелец КАК ФизЛицо,
МИНИМУМ(ВЫБОР
КОГДА Образование.ВидОбразования ПОДОБНО "%Высшее%" ТОГДА 1
КОГДА Образование.ВидОбразования ПОДОБНО "%Среднее%" ТОГДА 2
ИНАЧЕ 3
КОНЕЦ) КАК Приоритет
ПОМЕСТИТЬ ВТ_Приоритеты
ИЗ
Справочник.ОбразованиеФизическихЛиц КАК Образование
СГРУППИРОВАТЬ ПО
Образование.Владелец
После того как мы получили таблицу с минимальным приоритетом для каждого сотрудника, нам остается только соединить её с исходными данными, чтобы получить само название вида образования. Этот подход позволяет полностью избежать дублирования.
Часто возникает проблема, когда у сотрудника вообще нет записей в регистре образования. В этом случае ЛЕВОЕ СОЕДИНЕНИЕ вернет NULL. Чтобы корректно отобразить такие записи как «Нет», используйте функцию ЕСТЬNULL.
Рассмотрим пример того, как собрать итоговый результат:
ВЫБРАТЬ
Сотрудники.Сотрудник,
ЕСТЬNULL(ПриоритетноеОбразование.ВидОбразования, "Нет") КАК ИтоговыйВид
ИЗ
РегистрСведений.КадроваяИсторияСотрудников КАК Сотрудники
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ОбразованиеФизическихЛиц КАК ПриоритетноеОбразование
ПО Сотрудники.ФизическоеЛицо = ПриоритетноеОбразование.Владелец
И ПриоритетноеОбразование.Приоритет = ВТ_Приоритеты.Приоритет
В ходе анализа мы выяснили, что использование оператора ПОДОБНО в условиях — это не самый производительный путь. Если ваша база данных растет, такие запросы начинают работать медленнее. Вместо этого мы рекомендуем:
УровеньОбразования) непосредственно в справочник ВидыОбразования.ВидОбразования = Перечисления.УровниОбразования.Высшее), что работает значительно быстрее.Таким образом, мы не только избавляемся от «задваивания» строк, но и делаем код запроса более читаемым и легким в сопровождении. Если вы будете использовать группировку по рангу, система сама выберет «лучшую» запись, отсекая все прочие, что и требовалось в задаче.
Применяйте данный метод в своих отчетах, и вы увидите, насколько проще становится управление сложными кадровыми данными без лишних дублей и громоздких условий в теле запроса.