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