Как выбрать несовпадающие строки из двух таблиц в запросе 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При работе с запросами в 1С часто возникает задача сравнения двух наборов данных. Нередко требуется найти товары, которые присутствуют только в одной из таблиц или имеют различное количество. При использовании ПОЛНОГО СОЕДИНЕНИЯ (FULL JOIN) разработчики часто сталкиваются с тем, что строки, содержащие NULL, пропадают из итоговой выборки. Давайте разберемся, почему это происходит и как правильно составить условие для получения корректного результата.

Почему не срабатывает простое условие сравнения?

Проблема кроется в логике обработки NULL значений. В языке запросов 1С NULL — это отсутствие значения. Когда мы делаем ПОЛНОЕ СОЕДИНЕНИЕ, у нас могут возникнуть ситуации, когда товар есть в Таблица1, но отсутствует в Таблица2 (в поле Таблица2.Количество будет NULL), или наоборот.

Если мы пишем условие ГДЕ Таблица1.Количество <> Таблица2.Количество, то система пытается сравнить число с NULL. Результатом такого сравнения не является ИСТИНА или ЛОЖЬ, результат становится неопределенным (UNKNOWN). В итоге, записи, где есть расхождение из-за отсутствия одной из сторон, просто отбрасываются фильтром.

Решение проблемы через функцию ЕСТЬNULL

Чтобы заставить запрос «видеть» отсутствие данных как ноль, мы используем функцию ЕСТЬNULL(). Эта функция позволяет заменить NULL на заданное значение (в нашем случае — 0). Рассмотрим оптимальный вариант запроса:


ВЫБРАТЬ
    ЕСТЬNULL(Таблица1.Товар, Таблица2.Товар) КАК Товар,
    ЕСТЬNULL(Таблица1.Количество, 0) КАК Количество1,
    ЕСТЬNULL(Таблица2.Количество, 0) КАК Количество2
ИЗ
    Таблица1 КАК Таблица1
        ПОЛНОЕ СОЕДИНЕНИЕ Таблица2 КАК Таблица2
        ПО Таблица1.Товар = Таблица2.Товар
ГДЕ
    ЕСТЬNULL(Таблица1.Количество, 0) <> ЕСТЬNULL(Таблица2.Количество, 0)

Разберем по шагам, что происходит в этом коде:

  1. Мы берем ПОЛНОЕ СОЕДИНЕНИЕ, чтобы гарантированно получить все строки из обеих таблиц.
  2. С помощью ЕСТЬNULL(..., 0) мы приводим все пустые значения к нулю. Теперь вместо сравнения 6 <> NULL система сравнивает 6 <> 0, что дает ИСТИНУ, и строка успешно попадает в выборку.
  3. Если в обоих полях оказались равные значения (например, 6 и 6), то 6 <> 6 дает ЛОЖЬ, и такие строки эффективно отфильтровываются.

Альтернативный вариант: логика через наличие данных

Иногда задача требует отсечь не только различающиеся по количеству, но и просто строки, которые присутствуют только в одной из таблиц. В таком случае можно комбинировать условия проверки на NULL.

Рассмотрим более строгий подход, когда мы явно проверяем факт отсутствия данных:


ВЫБРАТЬ
    ЕСТЬNULL(Таблица1.Товар, Таблица2.Товар) КАК Товар,
    ЕСТЬNULL(Таблица1.Количество, 0) КАК Количество1,
    ЕСТЬNULL(Таблица2.Количество, 0) КАК Количество2
ИЗ
    Таблица1 КАК Таблица1
        ПОЛНОЕ СОЕДИНЕНИЕ Таблица2 КАК Таблица2
        ПО (Таблица1.Товар = Таблица2.Товар)
ГДЕ
    (Таблица1.Количество ЕСТЬ NULL)
    ИЛИ (Таблица2.Количество ЕСТЬ NULL)
    ИЛИ (Таблица1.Количество <> Таблица2.Количество)

Этот вариант особенно полезен, если вам нужно точно контролировать логику включения строк, где одна из сторон полностью отсутствует в другой таблице. Использование конструкции ЕСТЬ NULL является стандартным способом проверки существования записи в связке с ПОЛНЫМ СОЕДИНЕНИЕМ.

Рекомендации по оптимизации

При работе с большими объемами данных помните о следующих моментах:

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

← На главную