Аналог SQL OFFSET и SKIP в 1С для разбития выборки запроса на страницы

Условие задачи

На языке запросов 1С необходимо с помощью языка запросов выбрать M записей начиная с записи N в справочнике или документе.

Отрезок M - M+N

Решение 1. Вариант "НЕ В"

Подобная задача часто используется, например, для пагинации выборки данных. Т.е. чтобы все записи выборки из результата выполнения запроса выбрать не сразу, а получать равными частями, чтобы было удобно их постранично выводить.

В MS SQL есть операторы TOP (ПЕРВЫЕ) и SKIP (ПРОПУСТИТЬ), которые позволяют это сделать. В запросах на платформе 1С нет оператора SKIP.
Подумаем, что можно с этим сделать.

Возьмем типовую 1С:Управление торговлей 11 и постараемся промоделировать ситуацию на реальной задаче.

Для справочника Номенклатура необходимо написать запрос, который выведет все элементы исключая группы с N = 10 и M = 10 с сортировкой по наименованию. Т.е. вывести элементы с десятого по девятнадцатый.

Мы имеем возможность в 1С использовать только получение первых записей. Поэтому идея решения на SQL следующая:

SELECT TOP N+M * FROM TABLE ORDER BY n
EXCEPT
SELECT TOP N * FROM TABLE ORDER BY n

Получим первые N+M элементов, и исключим из выборки первые N, в результате у нас останется искомое M элементов начиная с N. Схематично:

Отрезок от 0 до N и от N до N+M

Выбираем сначала от 0 до N+M и исключаем от 0 до N. А теперь переиначим на языке 1С. В результате получим вот такой запрос:

ВЫБРАТЬ ПЕРВЫЕ 10 // M
    Номенклатура.Ссылка КАК Ссылка
ИЗ
    Справочник.Номенклатура КАК Номенклатура
ГДЕ	
    НЕ Номенклатура.Ссылка В
                (ВЫБРАТЬ ПЕРВЫЕ 10 // N
                    Номенклатура.Ссылка КАК Ссылка
                ИЗ
                    Справочник.Номенклатура КАК Номенклатура
                ГДЕ
                    Номенклатура.ЭтоГруппа = ЛОЖЬ
                УПОРЯДОЧИТЬ ПО
                    Номенклатура.Наименование,
                    Ссылка)
    И Номенклатура.ЭтоГруппа = ЛОЖЬ

УПОРЯДОЧИТЬ ПО
    Наименование,
    Ссылка

Запрос результат

Проверяем в справочнике Номенклатура:

То, что должны получить

Получаем искомый результат. То, что и хотели получить. Единственный нюанс - это рекомендации фирмы 1С, что нежелательно использовать конструкцию "НЕ В (...)" (как и В (...)). Будет полное сканирование таблиц, что не очень хорошо отразится на производительности.

Важно! Выборки (то что в условии НЕ В ... и в главном запросе) должны быть с одинаковым упорядочиванием (у нас по наименованию и далее по ссылке) и упорядочивание должно быть всегда по какому-либо полю. Иначе запросы могут отработать не верно и вернуть не те результаты. Если поля упорядочивания нет, то можно использовать поле "Ссылка".

Решение 2. Вариант "Временная таблица"

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

ВЫБРАТЬ ПЕРВЫЕ 10 // N
    Номенклатура.Ссылка КАК Ссылка
ПОМЕСТИТЬ ВТ_1
ИЗ
    Справочник.Номенклатура КАК Номенклатура
ГДЕ
    Номенклатура.ЭтоГруппа = ЛОЖЬ

УПОРЯДОЧИТЬ ПО
    Номенклатура.Наименование,
    Ссылка
    
ИНДЕКСИРОВАТЬ ПО
    Ссылка    
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ ПЕРВЫЕ 10 // M
    Номенклатура.Ссылка КАК Ссылка
ИЗ
    Справочник.Номенклатура КАК Номенклатура
        ЛЕВОЕ СОЕДИНЕНИЕ ВТ_1 КАК ВТ_1
        ПО (Номенклатура.Ссылка = ВТ_1.Ссылка)
ГДЕ
    ВТ_1.Ссылка ЕСТЬ NULL
    И Номенклатура.ЭтоГруппа = ЛОЖЬ

УПОРЯДОЧИТЬ ПО
    Номенклатура.Наименование,
    Ссылка

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

Но и тут есть свои нюансы. Мы тратим время на создание временной таблицы. Это будет иметь смысл, если данных много, но если их мало, изначально, в справочнике Номенклатура, то решение 1, будет работать быстрее. Тоже вопрос, надо ли индексировать ВТ_1 по ссылке? Если данных мало, то смысла в этой операции скорее нет, чем есть, но все резко меняется, если данных становится гораздо больше.

Выводы

Решение 1, в целом, способ достаточно хороший и может быть использован в реальной работе. Самое главное, что он работает и позволяет обходить ограничение на использование оператора SKIP в запросах, но с нюансами по производительности.

Решение 2 создает временную таблицу, но быстрее исключает данные при исключении. Суммарно эти две операции надо считать вместе (создание ВТ + выборка с исключением). Да и в целом этот способ будет наверное изначально предпочтительней.

Изображение автора статьи

Основатель и директор по развитию Софтонит. Практикующий руководитель разработки. Эксперт в области автоматизации техподдержки

Загрузка...
Поделитесь статьей
Рекомендуем почитать
Статьи Решение проблемы "Обнаружено нарушение целостности системы 1С"

На сегодняшний день любой, пользующийся популярностью у пользователей программный продукт подвергается "пиратским" взломам и соответственно нелегальному использованию. Не исключением будут и программы от всеми известной в России фирмы 1С. Каждый разработчик старается бороться с подобным незаконным использованием своих продуктов по-разному. Так, например, разработчики 1С с 1-ого февраля 2021 года, массово запустили механизм, который определяет легальность использования программы 1С. В случае, если программа была взломана и используется незаконно конечные пользователи получают ошибку "Обнаружено нарушение целостности системы". Сегодня в публикации разберем причины появления данной ошибки, а также расскажем как решить возникшую проблему. 

Статьи Подключение терминала сбора данных к 1С

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

Статьи Настройка Apache для работы 1С через HTTPS (SSL)

Безопасность для многих всегда идет на первом месте, многие интернет-гиганты, типа Google даже добавляют в свои браузеры предупреждения, что соединение не безопасно, если на сайте не используется SSL-сертификат.
1С:Предприятие тоже может работать по протоколу HTTPS.
Мы предлагаем статью-инструкцию, как настроить HTTPS в Apache таким образом, чтобы 1С:Предприятие работало без проблем через SSL.

Статьи Ошибка HTTP 500.0 - Internal Server Error после публикации базы 1С на веб-сервере IIS

Рассмотрим ошибку, которая может возникать при публикации информационной базы 1С на web-сервере IIS Windows.
Попытаемся ее решить. Ошибка HTTP 500.0 - Internal Server Error.

Статьи Как удалить данные по организации в базе 1С?

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

Статьи Как включить отладку на сервере 1С:Предприятия?

Все мы прекрасно знаем, что отладка это прекрасный механизм в платформе 1С, который позволяет быстро найти проблему и решить ее путем пошаговых операций и просмотра значений переменных. Но при использовании серверной базы 1С механизм отладки по умолчанию выключен. А как быть, если надо найти проблему? В этой статье давайте постараемся в этом вопросе разобраться.

0 / 0