← Назад к вопросам

Декартово произведение таблиц в запросе

1.6 Junior🔥 111 комментариев
#Запросы и оптимизация

Условие

Ответьте на вопрос: в таблице А 10 записей, в таблице В 10 записей. Запрос ВЫБРАТЬ * ИЗ А, В сколько записей вернёт?

Напишите запрос, демонстрирующий декартово произведение таблиц, и объясните результат.

Ответ

Запрос вернёт 100 записей (10 × 10), так как без условия соединения происходит декартово произведение таблиц — каждая запись из первой таблицы соединяется с каждой записью второй таблицы.

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Решение

Ответ на вопрос

Запрос вернёт 100 записей.

Причина: каждая запись из таблицы А (10 записей) соединяется с каждой записью из таблицы В (10 записей), что даёт в результате 10 × 10 = 100 записей.

Что такое декартово произведение

Декартово произведение — это операция в теории множеств, которая создаёт все возможные пары элементов из двух множеств. В контексте SQL/1С это означает соединение таблиц без явного условия соединения (ON).

Математически: Если множество A = {a₁, a₂, ..., aₙ} и множество B = {b₁, b₂, ..., bₘ}, то A × B = {(a₁,b₁), (a₁,b₂), ..., (aₙ,bₘ)}, где |A × B| = |A| × |B| = n × m.

Демонстрирующий запрос 1: Явное декартово произведение

Выбрать
    А.Ссылка Как АСсылка,
    А.Наименование Как АНаименование,
    В.Ссылка Как ВСсылка,
    В.Наименование Как ВНаименование
Из
    Справочник.ТаблицаА Как А,
    Справочник.ТаблицаВ Как В

Результат: Если в А 10 записей, в В 10 записей, то результат будет 100 строк.

Демонстрирующий запрос 2: С явным ДЕКАРТОВО СОЕДИНЕНИЕ

Выбрать
    А.Ссылка Как АСсылка,
    А.Наименование Как АНаименование,
    В.Ссылка Как ВСсылка,
    В.Наименование Как ВНаименование,
    КОЛИЧЕСТВО(*) Над (Раздел Все) Как ВсегоСтрок
Из
    Справочник.ТаблицаА Как А
    Декартово Соединение Справочник.ТаблицаВ Как В

Описание: Явное использование ДЕКАРТОВО СОЕДИНЕНИЕ для ясности. Добавлено окно для подсчёта общего количества строк.

Демонстрирующий запрос 3: Без условия ON (неявное декартово произведение)

Выбрать
    А.Ссылка Как АСсылка,
    А.Наименование Как АНаименование,
    В.Ссылка Как ВСсылка,
    В.Наименование Как ВНаименование
Из
    Справочник.ТаблицаА Как А
    Внутреннее Соединение Справочник.ТаблицаВ Как В
        На 1 = 1  // Всегда истинно — создаёт декартово произведение

Описание: Условие "1 = 1" всегда истинно, поэтому создаётся декартово произведение.

Демонстрирующий запрос 4: Подсчёт результатов

Выбрать
    КОЛИЧЕСТВО(*) Как КоличествоСтрок
Из
    Справочник.ТаблицаА Как А,
    Справочник.ТаблицаВ Как В

Результат: 100 (при 10 записях в А и 10 в В).

Демонстрирующий запрос 5: С дополнительной таблицей

// Если А = 10, В = 10, С = 5
// То декартово произведение А, В, С = 10 × 10 × 5 = 500

Выбрать
    А.Ссылка Как АСсылка,
    В.Ссылка Как ВСсылка,
    С.Ссылка Как ССсылка,
    КОЛИЧЕСТВО(*) Над (Раздел Все) Как ВсегоСтрок
Из
    Справочник.ТаблицаА Как А,
    Справочник.ТаблицаВ Как В,
    Справочник.ТаблицаС Как С

Результат: 500 записей (10 × 10 × 5).

Демонстрирующий запрос 6: С фильтром (WHERE) на декартовом произведении

Выбрать
    А.Ссылка Как АСсылка,
    А.Наименование Как АНаименование,
    В.Ссылка Как ВСсылка,
    В.Наименование Как ВНаименование
Из
    Справочник.ТаблицаА Как А,
    Справочник.ТаблицаВ Как В
Где
    А.Ключевое_Поле = В.Ключевое_Поле  // Фильтруем из 100 строк

Описание: Сначала создаётся декартово произведение (100 строк), затем WHERE фильтрует результат. В этом случае вернутся только соединённые пары (если есть совпадения).

Сравнение: Правильное соединение VS Декартово произведение

// НЕПРАВИЛЬНО: Декартово произведение (100 строк)
Выбрать
    А.Наименование Как А,
    В.Наименование Как В
Из
    Справочник.ТаблицаА Как А,
    Справочник.ТаблицаВ Как В

// ПРАВИЛЬНО: Соединение по условию (предположим, 20 совпадений)
Выбрать
    А.Наименование Как А,
    В.Наименование Как В
Из
    Справочник.ТаблицаА Как А
    Внутреннее Соединение Справочник.ТаблицаВ Как В
        На А.Ключ = В.Ключ  // Явное условие соединения

Практический пример: когда полезно декартово произведение

// Создание всех комбинаций (размеры × цвета)
Выбрать
    Размеры.Наименование Как Размер,
    Цвета.Наименование Как Цвет,
    Размеры.Наименование + " " + Цвета.Наименование Как СКУ
Из
    Справочник.Размеры Как Размеры,  // 5 размеров
    Справочник.Цвета Как Цвета        // 4 цвета
// Результат: 5 × 4 = 20 комбинаций

Применение: Для создания всех возможных комбинаций товаров (размер × цвет × материал и т.д.).

Использование в коде 1С

Процедура ДемонстрацияДекартоваПроизведения()
    
    // Подготовка данных
    ТаблицаА = Новый ТаблицаЗначений();
    ТаблицаА.Колонки.Добавить("ИД", , "Число");
    ТаблицаА.Колонки.Добавить("Значение", , "Строка");
    
    Для И = 1 По 10 Цикл
        Строка = ТаблицаА.Добавить();
        Строка.ИД = И;
        Строка.Значение = "А" + И;
    КонецЦикла;
    
    ТаблицаВ = Новый ТаблицаЗначений();
    ТаблицаВ.Колонки.Добавить("ИД", , "Число");
    ТаблицаВ.Колонки.Добавить("Значение", , "Строка");
    
    Для И = 1 По 10 Цикл
        Строка = ТаблицаВ.Добавить();
        Строка.ИД = И;
        Строка.Значение = "В" + И;
    КонецЦикла;
    
    // Создание запроса с декартовым произведением
    ТекстЗапроса = "Выбрать
        |    А.ИД Как АИД,
        |    А.Значение Как АЗначение,
        |    В.ИД Как ВИД,
        |    В.Значение Как ВЗначение
        |Из
        |    &ТаблицаА Как А,
        |    &ТаблицаВ Как В";
    
    Запрос = Новый Запрос(ТекстЗапроса);
    Запрос.УстановитьПараметр("ТаблицаА", ТаблицаА);
    Запрос.УстановитьПараметр("ТаблицаВ", ТаблицаВ);
    
    РезультатЗапроса = Запрос.Выполнить();
    РезультатТаблица = РезультатЗапроса.Выгрузить();
    
    Сообщить("Количество строк в результате: " + РезультатТаблица.Количество()); // 100
    
    // Вывод первых 5 строк для проверки
    Для И = 0 По Мин(4, РезультатТаблица.Количество() - 1) Цикл
        Строка = РезультатТаблица[И];
        Сообщить(Строка.АЗначение + " x " + Строка.ВЗначение);
    КонецЦикла;
    
КонецПроцедуры

Ошибка: нежелательное декартово произведение

// ОШИБКА: Забыли условие ON
Выбрать
    З.Наименование Как Заказ,
    Т.Наименование Как Товар
Из
    Документ.Заказ Как З
    Внутреннее Соединение Документ.Заказ.Товары Как Т
        // Забыли: На З.Ссылка = Т.Ссылка
// Результат: декартово произведение всех заказов и всех товарных строк!

// ПРАВИЛЬНО:
Выбрать
    З.Наименование Как Заказ,
    Т.Наименование Как Товар
Из
    Документ.Заказ Как З
    Внутреннее Соединение Документ.Заказ.Товары Как Т
        На З.Ссылка = Т.Ссылка

Ключевые моменты

  1. Декартово произведение = все возможные пары элементов из двух таблиц
  2. Формула: |A × B| = |A| × |B|
  3. Опасность: может резко увеличить объём данных (например, 1000 × 1000 = 1,000,000 строк)
  4. Избегание: всегда используйте явное условие ON в соединениях
  5. Применение: полезно для создания комбинаций, кросс-табуляции, перечисления вариантов
  6. Синтаксис: используйте запятую между таблицами или ключевое слово ДЕКАРТОВО СОЕДИНЕНИЕ

Производительность

Декартово произведение может быть очень затратным по памяти и процессору:

  • 100 × 100 = 10,000 строк
  • 1,000 × 1,000 = 1,000,000 строк
  • 10,000 × 10,000 = 100,000,000 строк (обычно вызывает ошибку памяти)

Всегда используйте с осторожностью и убедитесь, что это именно то, что вам нужно.

Декартово произведение таблиц в запросе | PrepBro