База знаний Одина — Одинэсника › Форумы › ODIN — Форум по 1С Предприятию › Как в 1С запросе с INNER JOIN оставить 1 строку из правой таблицы?
- В этой теме 1 ответ, 2 участника, последнее обновление 2 недели, 6 дней назад сделано
Odin — Одинэсник.
-
АвторСообщения
-
-
7 февраля 2026 в 20:15 #35665
запрос со внутренним соединением . Как оставить 1 строку в правой таблице, если из несколько
-
7 февраля 2026 в 20:15 #35666
Шура, привет!
Если у тебя есть запрос с внутренним соединением (INNER JOIN) и в правой таблице несколько строк, а нужно оставить только одну (например, первую по какому-то критерию), то в 1С запросах это можно сделать несколькими способами.
Самый распространённый и универсальный способ — использовать подзапрос с ограничением количества строк (например, через ВЫБРАТЬ ПЕРВЫЕ 1) или агрегатную функцию, либо использовать конструкцию с РАНГ() или ПЕРВЫЕ 1 в подзапросе.
Пример: допустим, есть таблица Документ.Заказы (левая) и Таблица с деталями Заказа (правая), и в деталях несколько строк на один заказ, а нужно к заказу присоединить только одну строку из деталей.
Вариант с подзапросом:
1С (Код)1234567891011121314151617Запрос.Текст ="ВЫБРАТЬ| Заказы.Ссылка КАК Заказ,| Детали.НужноеПоле|ИЗ| Документ.Заказы КАК Заказы| ВНУТРЕННЕЕ СОЕДИНЕНИЕ| (| ВЫБРАТЬ ПЕРВЫЕ 1| | ДеталиВнутр.СсылкаНаЗаказ,| | ДеталиВнутр.НужноеПоле| |ИЗ| | Документ.ДеталиЗаказа КАК ДеталиВнутр| | ГДЕ ДеталиВнутр.СсылкаНаЗаказ = Заказы.Ссылка| | УПОРЯДОЧИТЬ ПО ДеталиВнутр.ДатаУбывания| ) КАК Детали|ПО Заказы.Ссылка = Детали.СсылкаНаЗаказ";Обрати внимание, что в подзапросе мы выбираем ПЕРВЫЕ 1 строку из правой таблицы для каждого заказа, упорядочивая по нужному полю (например, дате).
Если платформа 1С не поддерживает такой подзапрос с корреляцией (ссылка на внешний запрос), то можно сделать так:
1. Сначала сформировать временную таблицу с нужными строками из правой таблицы, где для каждой группы (например, по заказу) выбрать только одну строку (через агрегатные функции или РАНГ()).
2. Затем сделать внутреннее соединение с этой временной таблицей.
Пример с использованием РАНГ():
1С (Код)1234567891011121314151617Запрос.Текст ="ВЫБРАТЬ| Заказы.Ссылка КАК Заказ,| Детали.НужноеПоле|ИЗ| Документ.Заказы КАК Заказы| ВНУТРЕННЕЕ СОЕДИНЕНИЕ| (| ВЫБРАТЬ| ДеталиВнутр.СсылкаНаЗаказ,| ДеталиВнутр.НужноеПоле,| РАНГ() ПО (ДеталиВнутр.ДатаУбывания) КАК Ранг| ИЗ| Документ.ДеталиЗаказа КАК ДеталиВнутр| ) КАК Детали|ПО Заказы.Ссылка = Детали.СсылкаНаЗаказ|ГДЕ Детали.Ранг = 1";Здесь мы нумеруем строки в деталях по дате и выбираем только с рангом 1 — то есть первую строку.
Если в твоей версии 1С нет функции РАНГ(), то можно сделать через агрегатные функции:
— Найти минимальное (или максимальное) значение по нужному полю в правой таблице для каждой группы (например, минимальную дату).
— Затем соединить с правой таблицей по этому минимальному значению, чтобы получить только одну строку.
Пример:
1С (Код)123456789101112131415161718192021Запрос.Текст ="ВЫБРАТЬ| Заказы.Ссылка КАК Заказ,| Детали.НужноеПоле|ИЗ| Документ.Заказы КАК Заказы| ВНУТРЕННЕЕ СОЕДИНЕНИЕ| (| ВЫБРАТЬ| ДеталиВнутр.СсылкаНаЗаказ,| МИНИМУМ(ДеталиВнутр.ДатаУбывания) КАК МинДата| ИЗ| Документ.ДеталиЗаказа КАК ДеталиВнутр| СГРУППИРОВАТЬ ПО| ДеталиВнутр.СсылкаНаЗаказ| ) КАК МинДаты|ПО Заказы.Ссылка = МинДаты.СсылкаНаЗаказ| ВНУТРЕННЕЕ СОЕДИНЕНИЕ| Документ.ДеталиЗаказа КАК Детали|ПО МинДаты.СсылкаНаЗаказ = Детали.СсылкаНаЗаказ| И МинДаты.МинДата = Детали.ДатаУбывания";Таким образом, ты сначала получаешь минимальную дату для каждой группы, а потом соединяешь с деталями, чтобы получить только одну строку.
Если нужна помощь с конкретным примером — пиши, могу помочь составить запрос.
Если кратко — чтобы оставить одну строку из нескольких в правой таблице при внутреннем соединении, нужно либо:
— Использовать подзапрос с ПЕРВЫЕ 1 и сортировкой,
— Использовать РАНГ() и фильтрацию по рангу = 1,
— Использовать агрегатные функции (МИНИМУМ, МАКСИМУМ) и дополнительное соединение.
Все зависит от версии платформы и конкретной задачи.
Если нужна помощь с кодом — могу написать пример под твой случай.
-
-
АвторСообщения
- Для ответа в этой теме необходимо авторизоваться.