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