таблице. Недостающим значениям столбцов другой таблицы при этом
присваивается значение NULL.
Возможны три варианта внешнего соединения двух таблиц (выборка
дополняется строками таблицы, стоящей слева от слова JOIN, или табли-
цы, стоящей справа, или обеих сразу), поэтому различают три вида внеш-
них соединений:
LEFT [OUTER] JOIN – левое внешнее соединение
RIGHT [OUTER] JOIN – правое внешнее соединение
FULL [OUTER] JOIN – полное внешнее соединение.
Например, перепишем предыдущий запрос (код, фамилия и средний
балл студента), используя внешнее соединение таким образом, чтобы
студенты, у которых вообще нет оценок, попали бы в список вывода с
NULL-значениями среднего балла.
SELECT st.cod_st, st.name_st, AVG (m.mark) avg_mark
FROM students st LEFT JOIN marks m ON st.cod_st=m.cod_st
GROUP BY st.cod_st, st.name_st
Мы уже знаем, что внутреннее соединение таблиц часто оформляет-
ся в тексте запроса, как выборка из декартова произведения. Можно ли
использовать этот способ для внешнего соединения?
В некоторых СУБД можно, но, как и все нестандартные конструк-
ции, это плохо влияет на переносимость запроса. Все же приведем вари-
ант записи внешнего соединения таблиц, используя синтаксис СУБД
Oracle (на примере того же самого запроса - код, фамилия и средний балл
студента).
SELECT st.cod_st, st.name_st, AVG (m/mark) avg_mark
FROM students st, marks m
WHERE st.cod_st=m.cod_st (+)
GROUP BY st.cod_st, st.name_st
Используемая здесь синтаксическая конструкция (+) добавляет фик-
тивные строки в таблицу marks для тех студентов, у которых нет оценок,
при этом в столбец mark помещается значение NULL.
Рассмотрим некоторые особенности использования функции
COUNT в запросах с внешим соединением таблиц. Пусть требуется вы-
вести количество оценок для каждого студента из таблицы students. Если
студент еще не имеет ни одной оценки, должно быть выведено количест-
во 0. Текст запроса, использующий операцию LEFT JOIN:
SELECT st.cod_st, st.name_st, COUNT(m.mark) count_mark
FROM students st LEFT JOIN marks m ON st.cod_st=m.cod_st
GROUP BY st.cod_st, st.name_st
Использование конструкции COUNT(m.mark) позволит получить
правильные результаты и вывести значение 0 для студентов, не имеющих
оценок. Однако, если использовать в этом же запросе COUNT(*), то для