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