4.3.3. Использование INSERT...SELECT для построения внешнего соединения

Рассмотренное в п.3.2.3 естественное соединение двух таблиц не включает тех строк какой-либо из них, для которых нет соответствующих строк в другой таблице. Например, если в таблицу Блюда были занесены под номером 34 сведения о Шашлыке, а рецепт его приготовления не был занесен в таблицу Рецепты, то при загрузке их естественного соединения в таблицу Временная:

    CREATE TABLE Временная
    	(	Вид	CHAR (8),
    		Блюдо	CHAR (60),
    		Рецепт	CHAR (560));

    INSERT
    INTO	Временная
    SELECT	Вид, Блюдо, Рецепт
    FROM	Блюда, Рецепты, Вид_блюд
    WHERE	Блюда.БЛ = Рецепты.БЛ
    AND	Блюда.В = Вид_блюд.В;

в ней не окажется строки с Шашлыком (в таблице Рецепты не обнаружен код 34, и строка с этим кодом исключена из результата).

Следовательно, в некотором смысле можно считать, что при обычном соединении теряется информация для таких несоответствующих строк. Однако иногда (как и в приведенном примере) может потребоваться способность сохранить эту информацию. В этом случае можно воспользоваться так называемым внешним соединением:

    INSERT
    INTO	Временная
    SELECT	Вид, Блюдо, Рецепт
    FROM	Блюда, Рецепты, Вид_блюд
    WHERE	Блюда.БЛ = Рецепты.БЛ
    AND	Блюда.В = Вид_блюд.В;

    INSERT
    INTO	Временная
    SELECT	Вид, Блюдо, “???”
    FROM	Блюда, Вид_блюд
    WHERE	Блюда.В = Вид_блюд.В
    AND	БЛ NOT IN
    	(	SELECT	БЛ
    		FROM	Рецепты);

В результате будет создана базовая таблица

Вид | Блюдо | Рецепт
--- | --- | ---
Закуска | Салат летний | Помидоры и яблоки нарезать...
Закуска | Салат мясной | Вареное охлажденное мясо, ...
. . .
Напиток | Кофе черный | Кофеварку или кастрюлю спо...
Напиток | Кофе на молоке | Сварить черный кофе, как ...
Горячее | Шашлык | ???

где первые 33 строки соответствуют первому INSERT и представляют собой проекцию естественного соединения таблиц Блюда и Рецепты по кодам блюд (БЛ), включающую три столбца. Последняя строка результата соответствует второму INSERT и сохраняет информацию о блюде Шашлык, рецепт котого пока не введен в таблицу Рецепты.

Заметим, что для внешнего соединения нужны два отдельных INSERT...SELECT. Однако тот же результат можно получить и одним INSERT...SELECT, используя фразу UNION, объединяющую предложения SELECT из двух INSERT:

    INSERT
    INTO	Временная
    SELECT	Вид, Блюдо, Рецепт
    FROM	Блюда, Рецепты, Вид_блюд
    WHERE	Блюда.БЛ = Рецепты.БЛ
    AND	Блюда.В = Вид_блюд.В
    UNION
    SELECT	Вид, Блюдо, “???”
    FROM	Блюда, Вид_блюд
    WHERE	Блюда.В = Вид_блюд.В
    AND	БЛ NOT IN
    	(	SELECT	БЛ
    		FROM	Рецепты);

4.3.2 | Содержание | 4.4