К статье
Практический материал

Разработка и Конфигурация · 10 мин

Выбрать первые 1 в запросе 1С: как работает и когда применять

Как работает конструкция ВЫБРАТЬ ПЕРВЫЕ 1 в запросе 1С: синтаксис, сортировка, типичные ошибки, производительность и примеры кода с пояснениями.

Конструкция ВЫБРАТЬ ПЕРВЫЕ 1 в языке запросов 1С ограничивает результат выборки одной записью. Она применяется, когда из таблицы нужна только одна строка — например, последний по дате документ, максимальная цена товара или актуальное значение периодического регистра сведений. Без этой конструкции запрос вернёт все подходящие строки, и разработчику придётся обрабатывать лишние данные в коде.

Ключевой момент, который часто упускают: «первые» — это не случайные и не «первые попавшиеся» записи в физическом порядке таблицы. Какая именно строка окажется первой, определяется сортировкой УПОРЯДОЧИТЬ ПО. Если сортировку не указать, СУБД вернёт произвольную запись из подходящих, и результат может меняться от выполнения к выполнению.

Ниже разобран синтаксис, роль упорядочивания, влияние на производительность, типичные ошибки и альтернативные способы получить одну запись.

Синтаксис конструкции ПЕРВЫЕ

Ключевое слово ПЕРВЫЕ указывается сразу после ВЫБРАТЬ, до списка полей. После него идёт целое число — количество возвращаемых записей. Для получения одной строки пишут ВЫБРАТЬ ПЕРВЫЕ 1.

ВЫБРАТЬ ПЕРВЫЕ 1

Номенклатура.Ссылка КАК Товар,

Номенклатура.Код КАК Код

ИЗ

Справочник.Номенклатура КАК Номенклатура

ГДЕ

НЕ Номенклатура.ПометкаУдаления

УПОРЯДОЧИТЬ ПО

Номенклатура.Код

Число после ПЕРВЫЕ может быть любым положительным целым: ПЕРВЫЕ 10 вернёт десять строк, ПЕРВЫЕ 100 — сто. Передать параметр вместо литерала напрямую нельзя — значение должно быть зашито в тексте запроса. Если количество нужно менять динамически, текст запроса формируют программно через подстановку строки.

Почему без УПОРЯДОЧИТЬ результат непредсказуем

Главная ошибка при использовании ПЕРВЫЕ 1 — отсутствие сортировки. Разработчик пишет запрос, тестирует его, получает «правильную» запись и решает, что всё работает. На самом деле СУБД просто вернула первую попавшуюся строку по физическому порядку чтения, который зависит от плана запроса, состояния индексов и статистики.

После реструктуризации, обновления платформы, изменения индексов или просто роста таблицы план запроса может измениться — и «первая» запись станет другой. Такие ошибки трудно поймать: код не падает, просто периодически возвращает не те данные.

Правило простое: если используется ПЕРВЫЕ, почти всегда нужна и секция УПОРЯДОЧИТЬ ПО. Направление сортировки выбирают по смыслу задачи: для последнего по времени документа — УБЫВ по дате, для минимального кода — по возрастанию.

ВЫБРАТЬ ПЕРВЫЕ 1

Реализация.Ссылка КАК Документ,

Реализация.Дата КАК Дата

ИЗ

Документ.РеализацияТоваровУслуг КАК Реализация

ГДЕ

Реализация.Контрагент = &Контрагент

И Реализация.Проведен

УПОРЯДОЧИТЬ ПО

Реализация.Дата УБЫВ

Как ПЕРВЫЕ влияет на производительность

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

Но выигрыш реализуется не всегда. Если сортировка идёт по полю без индекса, серверу придётся прочитать и отсортировать все подходящие строки, чтобы определить первую. В этом случае ПЕРВЫЕ 1 почти не экономит время по сравнению с полной выборкой. Поэтому поля, по которым выполняется упорядочивание в часто выполняемых запросах, должны быть проиндексированы.

Ещё один нюанс — соединения. Если ПЕРВЫЕ применяется к результату соединения нескольких таблиц, СУБД сначала строит соединение, а потом отбирает строки. Для таких сценариев часто выгоднее вынести ограничение во временную таблицу или вложенный запрос.

Типичные сценарии применения

Последний документ или запись по дате

Самый частый случай: найти последний проведённый документ контрагента, последнюю установленную цену, последнее изменение статуса. Здесь ПЕРВЫЕ 1 сочетается с сортировкой по дате по убыванию. Для периодических регистров сведений вместо ручного запроса обычно используют виртуальную таблицу СрезПоследних — она спроектирована именно под эту задачу и работает предсказуемее.

Проверка существования записи

Когда нужно только узнать, есть ли хотя бы одна строка, удовлетворяющая условию, ПЕРВЫЕ 1 сокращает объём передаваемых данных. Результат проверяют методом Пустой() у результата запроса или выборки. Это удобнее, чем выбирать все строки и считать их.

Получение одного значения для подстановки

Например, нужно подставить в отчёт основной договор контрагента или ответственного сотрудника. Запрос с ПЕРВЫЕ 1 возвращает одно значение, которое присваивают переменной после проверки, что выборка не пустая.

Порядок действий
  1. 1
    Определите, по какому критерию выбирается «первая» запись: дата, код, приоритет
  2. 2
    Напишите запрос с ВЫБРАТЬ ПЕРВЫЕ 1 и отбором ГДЕ
  3. 3
    Добавьте УПОРЯДОЧИТЬ ПО по выбранному критерию с нужным направлением
  4. 4
    Проверьте результат на тестовых данных, включая случай пустой выборки
  5. 5
    В коде обработайте ситуацию, когда запись не найдена

Обработка результата в коде

Даже с ПЕРВЫЕ 1 запрос возвращает таблицу результата, а не одиночное значение. Поэтому работают стандартные методы: Выбрать() для обхода или Выгрузить() для получения таблицы значений. Перед обращением к полям обязательно проверяют, что запись найдена.

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ ПЕРВЫЕ 1

| Цены.Цена КАК Цена

|ИЗ

| РегистрСведений.ЦеныНоменклатуры КАК Цены

|ГДЕ

| Цены.Номенклатура = &Номенклатура

|УПОРЯДОЧИТЬ ПО

| Цены.Период УБЫВ";

Запрос.УстановитьПараметр("Номенклатура", Товар);

Выборка = Запрос.Выполнить().Выбрать();

Если Выборка.Следующий() Тогда

ТекущаяЦена = Выборка.Цена;

Иначе

ТекущаяЦена = 0; // записи нет — задаём значение по умолчанию

КонецЕсли;

Пропуск проверки Следующий() — частая причина ошибок: если запись не найдена, обращение к полям выборки вернёт неопределённое значение или вызовет исключение в зависимости от способа доступа.

Типичные ошибки
01
Нет УПОРЯДОЧИТЬ ПО — запрос возвращает произвольную запись, результат плавает
02
Сортировка по неиндексированному полю на большой таблице — запрос выполняется медленно
03
Обращение к полям выборки без проверки Следующий() — ошибка или пустые данные при отсутствии записи
04
Использование ПЕРВЫЕ 1 вместо СрезПоследних для периодических регистров — сложнее код и выше риск ошибки в условиях
05
Ожидание, что ПЕРВЫЕ 1 вернёт значение, а не таблицу — путаница при обработке результата

Альтернативы ПЕРВЫЕ 1

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

Если нужно не значение, а факт наличия записи, иногда достаточно агрегатной функции КОЛИЧЕСТВО или выборки с группировкой. А когда требуется максимум или минимум по числовому полю, корректнее использовать МАКСИМУМ / МИНИМУМ, а не сортировку с ПЕРВЫЕ 1 — так запрос честнее отражает намерение.

Сравнение вариантов

ПЕРВЫЕ 1 + УПОРЯДОЧИТЬ ПО

Универсально: одна запись по любому критерию из любых таблиц. Требует явной сортировки и индекса

СрезПоследних

Для периодических регистров сведений: актуальные значения на дату по всем измерениям. Не подходит для документов и справочников

МАКСИМУМ / МИНИМУМ

Когда нужно только экстремальное значение поля, а не вся строка. Не возвращает связанные поля записи

КОЛИЧЕСТВО

Когда нужно лишь проверить наличие записей. Не даёт самих данных

Проверка корректности запроса

Перед тем как встраивать запрос в прикладной код, его стоит проверить в консоли запросов на реальных или копийных данных. Проверяют три вещи: возвращается ли ожидаемая запись, что происходит при пустом результате и не меняется ли ответ при повторных выполнениях.

Дополнительно полезно выполнить запрос без ПЕРВЫЕ и посмотреть первые несколько строк с той же сортировкой — так видно, какие записи «конкурируют» за первое место, и нет ли среди них неожиданных дублей по ключу сортировки. Если по полю сортировки возможны одинаковые значения (например, несколько документов с одной датой), добавьте в упорядочивание второй критерий — ссылку или уникальный идентификатор, чтобы результат был стабильным.

Контрольные точки

Как проверить результат

Стабильность результата
Норма

При повторных выполнениях возвращается одна и та же запись

Тревожный признак

Запись меняется от выполнения к выполнению — нет или недостаточна сортировка

Пустой результат
Норма

Код корректно обрабатывает отсутствие записи

Тревожный признак

Ошибка или неопределённое значение при пустой выборке

Скорость на больших данных
Норма

Запрос выполняется быстро, в плане используется индекс

Тревожный признак

Полное сканирование таблицы, время растёт с объёмом данных

Частые вопросы

Чем ПЕРВЫЕ отличается от РАЗЛИЧНЫЕ?

ПЕРВЫЕ ограничивает количество возвращаемых строк, а РАЗЛИЧНЫЕ убирает дубликаты из результата. Это независимые конструкции, их можно комбинировать: ВЫБРАТЬ РАЗЛИЧНЫЕ ПЕРВЫЕ 5 вернёт пять уникальных строк.

Можно ли передать количество записей параметром?

Нет, число после ПЕРВЫЕ должно быть литералом в тексте запроса. Если количество нужно менять динамически, текст запроса формируют программно, подставляя целое число через СтрШаблон или конкатенацию с контролем типа значения.

Что вернёт ВЫБРАТЬ ПЕРВЫЕ 1, если подходящих записей нет?

Запрос выполнится без ошибки и вернёт пустой результат. Метод Пустой() результата запроса вернёт Истина, а выборка не перейдёт ни на одну запись — Следующий() вернёт Ложь. Это нужно обрабатывать в коде.

Работает ли ПЕРВЫЕ в иерархических запросах и с итогами?

Да, ограничение применяется к итоговому результату после группировок и иерархии.

Как выбрать последнюю запись периодического регистра сведений?

Правильнее использовать виртуальную таблицу СрезПоследних с указанием периода и условия по измерениям. Ручной запрос с ПЕРВЫЕ 1 и сортировкой по периоду по убыванию тоже работает, но требует аккуратного учёта всех измерений и легче допускает ошибки.

Почему запрос с ПЕРВЫЕ 1 всё равно выполняется медленно?

Скорее всего, сортировка идёт по полю без индекса: СУБД вынуждена прочитать и отсортировать все подходящие строки, чтобы найти первую. Проверьте план запроса и добавьте индекс по полям условия и упорядочивания.

Итог

Что важно запомнить

ВЫБРАТЬ ПЕРВЫЕ 1 возвращает одну строку результата, и какая именно — определяет сортировка УПОРЯДОЧИТЬ ПО. Без сортировки выбор недетерминирован. Для скорости нужен индекс по полям упорядочивания, для надёжности — обработка пустого результата и второй критерий сортировки при возможных дублях.