Аналог 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С. В случае, если программа была взломана и используется незаконно конечные пользователи получают ошибку "Обнаружено нарушение целостности системы". Сегодня в публикации разберем причины появления данной ошибки, а также расскажем как решить возникшую проблему. 

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

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

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

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

Статьи Как установить Linux Ubuntu и настроить в качестве сервера

Хотите создать мощный сервер на базе Linux? Чтобы начать, нужно ознакомиться с установкой и настройкой операционной системы. В новой статье мы расскажем о процессе развертывания сервера на базе Linux. И в последующих выпусках мы будем устанавливать и настраивать PostgreSQL, платформу 1С и производить публикацию ИБ на веб-сервере «Apache». Готовы узнать все необходимое для успешного развертывания? Читайте нашу новую статью!

Статьи Перенос программной лицензии 1С на другой компьютер

Инструкция как перенести программную лицензию 1С на другой компьютер, если известны все данные активации.

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

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

0 / 0