"Левый" и "правый" значимы в логике спецификаций внешнего соединения. Внешнее соединение может быть левым, правым и полным. Каждый тип внешнего соединения создает различный выходной набор данных из тех же входных потоков. Ключевые слова LEFT, RIGHT и FULL достаточны для установления факта, что соединение "внешнее"; ключевое слово OUTER является необязательной частью синтаксиса.
LEFT OUTER JOIN
Левое внешнее соединение (LEFT OUTER[78] JOIN) в запросе создает набор данных, состоящий из полностью заполненных столбцов, где найдены соответствующие строки (как и во внутреннем соединении), а также частично заполненных строк для каждого экземпляра, где соответствие правой стороны не найдено для ключа левой стороны. Несоответствующие столбцы будут "заполнены" значением NULL. Вот оператор, использующий те же входные потоки, что и наш пример INNER JOIN:
SELECT
Table1.PK,
Table1.COL1,
Table2.PKX,
Table2.COLX
FROM Table1 LEFT OUTER JOIN Table2
ON Table1.PK = Table2.FK
WHERE ... <условия-поиска>
На рис. 22.2 показано, как будут объединены потоки для левого соединения.
Рис. 22.2. Левое соединение
В этом случае, вместо того чтобы отбрасывать строки левого потока, для которых нет соответствия в правом потоке, запрос создает строку, содержащую данные из левого потока, и NULL для каждого указанного в правом потоке столбца.
RIGHT OUTER JOIN
Правое внешнее соединение (RIGHT OUTER JOIN) в запросе создает набор данных, содержащий полностью заполненные столбцы, где были найдены соответствующие строки (как и во внутреннем соединении), а также частично заполненные строки для каждого экземпляра, где существует правая строка, не имеющая соответствия с левым потоком. Не имеющие соответствия столбцы будут "заполнены" значением NULL. Вот оператор, использующий те же входные потоки, что и наш пример INNER JOIN. Необязательное ключевое слово OUTER здесь отсутствует.
SELECT
Table1.PK,
Table1.COL1,
Table2.PKX,
Table2.COLX
FROM Table1 RIGHT JOIN Table2
ON Table1.PK = Table2.FK
WHERE ... <условия-поиска>
На рис. 22.3 показано, как будут объединены потоки для правого соединения.
Рис. 22.3. Правое соединение
FULL OUTER JOIN
Полное внешнее соединение (FULL OUTER JOIN) является целиком включающим. Оно возвращает одну строку для каждой пары соответствующих потоков и одну частично заполненную строку для каждой строки из каждого потока, где соответствие не было найдено. Данное соединение объединяет поведение правого и левого соединений.
Рис. 22.4. Полное соединение
Вот оператор, использующий те же входные потоки, что и наш пример INNER JOIN:
SELECT
Table1.PK,
Table1.COL1,
Table2.PKX,
Table2.COLX
FROM Table1 FULL JOIN Table2
ON Table1.PK = Table2.FK
WHERE ... <условия-поиска>
На рис. 22.4 показано, как будут объединены потоки для полного соединения.
Перекрестные соединения
Firebird не поддерживает языковых элементов для перекрестного соединения (CROSS JOIN), которое создает набор данных, являющийся декартовым произведением двух таблиц. То есть для каждой строки левого потока выходной поток будет содержать каждую строку из правого потока. В редких случаях, когда вам нужно декартово произведение, вы можете использовать синтаксис SQL-89 без каких-либо критериев соединения в предложении WHERE, например:
SELECT T1.*, Т2.* FROM T1 TABLE1, T2 TABLE2;
Обработчик запросов Firebird иногда внутренне создает перекрестные соединения, когда конструирует "реки" в процессе соединения операций (см. разд. "Темы оптимизации" этой главы).
Естественные соединения
Firebird не поддерживает естественное соединение (NATURAL JOIN), также известное как эквисоединение (EQUI JOIN), которое создает набор данных, связывая два потока на основе соответствия столбцов, использующих общие идентификаторы столбцов с одинаковыми значениями. В Firebird вы всегда должны указывать условия соединения.
Двусмысленность в запросах JOIN
В различных книгах по теории баз данных сказано, что двусмысленность может существовать, только когда некоторые имена столбцов появляются в нескольких потоках. Человек, практически работающий с базами данных, может рассказать другую историю. Вопрос устранения двусмысленности отпадает в зависимости от способа, каким сервер базы данных реализует синтаксический разбор, создание потоков и сортировку, которые выполняются в процессе операции соединения.
InterBase был снисходителен к отклонениям от недвусмысленности в синтаксисе соединений - иногда с неудачными результатами. Если вы переносите существующий код вашего приложения, работавшего с InterBase, не пугайтесь исключений SQL, которые выдаст Firebird в процессе первого тестового выполнения запросов с соединениями. Он покажет вам места в вашем коде, где раньше допускалось выполнение запросов, которые могли возвращать неверные результаты.