Декартово произведение таблиц в запросе
Условие
Ответьте на вопрос: в таблице А 10 записей, в таблице В 10 записей. Запрос ВЫБРАТЬ * ИЗ А, В сколько записей вернёт?
Напишите запрос, демонстрирующий декартово произведение таблиц, и объясните результат.
Ответ
Запрос вернёт 100 записей (10 × 10), так как без условия соединения происходит декартово произведение таблиц — каждая запись из первой таблицы соединяется с каждой записью второй таблицы.
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Решение
Ответ на вопрос
Запрос вернёт 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
Выбрать
З.Наименование Как Заказ,
Т.Наименование Как Товар
Из
Документ.Заказ Как З
Внутреннее Соединение Документ.Заказ.Товары Как Т
// Забыли: На З.Ссылка = Т.Ссылка
// Результат: декартово произведение всех заказов и всех товарных строк!
// ПРАВИЛЬНО:
Выбрать
З.Наименование Как Заказ,
Т.Наименование Как Товар
Из
Документ.Заказ Как З
Внутреннее Соединение Документ.Заказ.Товары Как Т
На З.Ссылка = Т.Ссылка
Ключевые моменты
- Декартово произведение = все возможные пары элементов из двух таблиц
- Формула: |A × B| = |A| × |B|
- Опасность: может резко увеличить объём данных (например, 1000 × 1000 = 1,000,000 строк)
- Избегание: всегда используйте явное условие ON в соединениях
- Применение: полезно для создания комбинаций, кросс-табуляции, перечисления вариантов
- Синтаксис: используйте запятую между таблицами или ключевое слово ДЕКАРТОВО СОЕДИНЕНИЕ
Производительность
Декартово произведение может быть очень затратным по памяти и процессору:
- 100 × 100 = 10,000 строк
- 1,000 × 1,000 = 1,000,000 строк
- 10,000 × 10,000 = 100,000,000 строк (обычно вызывает ошибку памяти)
Всегда используйте с осторожностью и убедитесь, что это именно то, что вам нужно.