В процессе разработки отчетов в системе 1С часто возникает задача «Top N в группах». Например, нам необходимо вывести не просто список всех документов, а выбрать только 10 самых крупных сделок для каждого контрагента. Поскольку в языке запросов 1С отсутствуют оконные функции (такие как ROW_NUMBER()), мы должны воспользоваться альтернативными методами. Рассмотрим их подробно.
Этот способ является наиболее предпочтительным с точки зрения читаемости кода и производительности на средних объемах данных. Мы используем условие ГДЕ Ссылка В (...), чтобы для каждого контрагента из внешнего запроса вычислить топ-10 документов во внутреннем подзапросе.
Рассмотрим реализацию:
ВЫБРАТЬ
Сделки.Контрагент,
Сделки.Ссылка,
Сделки.СуммаРуб
ИЗ
Документ.Сделка КАК Сделки
ГДЕ
Сделки.Ссылка В (
ВЫБРАТЬ ПЕРВЫЕ 10
Сделки1.Ссылка
ИЗ
Документ.Сделка КАК Сделки1
ГДЕ
Сделки1.Контрагент = Сделки.Контрагент
УПОРЯДОЧИТЬ ПО
Сделки1.СуммаРуб УБЫВ
)
УПОРЯДОЧИТЬ ПО
Сделки.Контрагент,
Сделки.СуммаРуб УБЫВ
Преимущества этого метода:
Этот метод основан на логическом вычислении «порядкового номера» сделки. Мы соединяем таблицу документов саму с собой по условию: «Контрагент совпадает, а сумма второй сделки больше или равна сумме первой». Это позволяет понять, какое место занимает текущая сделка в списке всех сделок конкретного контрагента.
Разберем этапы реализации:
ВременнуюТаблицу для упрощения обработки.ЛЕВОЕ СОЕДИНЕНИЕ временной таблицы с самой собой по условию совпадения контрагента и неравенства сумм (или дат/ссылок для уникальности).Пример логики соединения:
ВЫБРАТЬ
ЛеваяТаблица.Контрагент,
ЛеваяТаблица.Ссылка,
ЛеваяТаблица.СуммаРуб
ИЗ
ВТ_Сделки КАК ЛеваяТаблица
ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Сделки КАК ПраваяТаблица
ПО ЛеваяТаблица.Контрагент = ПраваяТаблица.Контрагент
И ЛеваяТаблица.СуммаРуб <= ПраваяТаблица.СуммаРуб
ГРУППИРОВАТЬ ПО
ЛеваяТаблица.Контрагент,
ЛеваяТаблица.Ссылка,
ЛеваяТаблица.СуммаРуб
ИМЕЮЩИЕ
КОЛИЧЕСТВО(ПраваяТаблица.Ссылка) <= 10
УПОРЯДОЧИТЬ ПО
ЛеваяТаблица.Контрагент,
ЛеваяТаблица.СуммаРуб УБЫВ
При работе с большими объемами данных (сотни тысяч или миллионы документов) следует учитывать несколько факторов:
СУММА(СуммаРуб) может привести к попаданию лишних записей в топ-10. Для точной сортировки всегда добавляйте второе поле, например, МоментВремени или Ссылка.ТаблицуЗначений и отсортировать их средствами самого языка 1С (метод Сортировать() и обход цикла с счетчиком). Это часто оказывается быстрее, чем сложные запросы к базе данных.ИНДЕКСИРОВАТЬ ПО для полей, участвующих в соединении (в нашем случае — Контрагент), чтобы ускорить работу запроса.Надеемся, что эти способы помогут вам успешно решить поставленную задачу и сделать отчеты более информативными!