JOIN

Данная статья уточняет правило из статьи SELECT

Версии сервера

0.91.01.5.31.5.41.5.52.02.0.32.0.42.12.53.0
INNER, OUTER+++++++++++
CROSS-----++++++
NATURAL, USING--------+++

Доступно в

DSQL, ESQL, ISQL, PSQL

Формат

<joined table> ::= 
  { <cross_join> | <qualified_join> | <named_columns_join> | <natural_join>}
<cross_join> ::= 
  <reference_expression_list> CROSS JOIN <reference_expression_list>
<qualified_join> ::=
  <reference_expression_list> <join type> JOIN <reference_expression_list>
    ON <join condition>
<named_columns_join> ::=
  <reference_expression_list> <join type> JOIN <reference_expression_list>
    USING ( <column list> )
<natural_join> ::=
  <reference_expression_list> NATURAL <join type> JOIN <table primary>
<join type> ::=
  [{INNER | {LEFT | RIGHT | FULL} [OUTER]}]

Описание

Далее во всех примерах в качестве <reference_expression_list> будут использоваться следующие две таблицы:

CREATE TABLE A( A INT, B INT, C INT);
CREATE TABLE B( A INT, B INT, D INT);

A

ABC
111
222
B
ABD
---------
103
224

<qualified_join>

“Обычное” соединение. Подразделяется на 4 типа ():

  1. Внутреннее (INNER JOIN)
  2. Внешнее Левое (LEFT OUTER JOIN)
  3. Внешнее Правое (RIGHT OUTER JOIN)
  4. Внешнее Полное (FULL OUTER JOIN)

Внутреннее Из таблиц выделяются все возможные пары, для которых условие соединения истинно

SELECT A.A AS AA, A.B AS AB, A.C AS AC, B.A AS BA, B.B AS BB, B.D AS BD
FROM A INNER JOIN B ON A.B <= B.B

Эквивалентно неявному соединению:

SELECT A.A AS AA, A.B AS AB, A.C AS AC, B.A AS BA, B.B AS BB, B.D AS BD
FROM A, B 
WHERE A.B <= B.B

Результат:

AAABACBABBBD
111224
222224

Внешнее Левое Из левой таблицы выбираются все записи. Из правой выбираются только те, которые удовлетворяют условию соединения . Если для какой-либо записи левой таблицы не нашлась ни одна пара, то столбцы правой таблицы заменяются NULL-ами.

SELECT A.A AS AA, A.B AS AB, A.C AS AC, B.A AS BA, B.B AS BB, B.D AS BD
FROM A LEFT JOIN B ON A.B = B.B

Результат:

AAABACBABBBD
111NULLNULLNULL
222224

Внешнее Правое Эквивалентно левому, если поменять таблицы местами.

SELECT A.A AS AA, A.B AS AB, A.C AS AC, B.A AS BA, B.B AS BB, B.D AS BD
FROM A RIGHT JOIN B ON A.B = B.B

Эквивалентно:

SELECT A.A AS AA, A.B AS AB, A.C AS AC, B.A AS BA, B.B AS BB, B.D AS BD
FROM B LEFT JOIN A ON A.B = B.B

Результат:

AAABACBABBBD
NULLNULLNULL103
222224

Внешнее Полное Представляет собой результат объединения левого и правого соединения

SELECT A.A AS AA, A.B AS AB, A.C AS AC, B.A AS BA, B.B AS BB, B.D AS BD
FROM A FULL JOIN B ON A.B = B.B

Результат:

AAABACBABBBD
111NULLNULLNULL
222224
NULLNULLNULL103

<cross_join>

Перекрестное соединение, или декартово произведение. Каждая строка левой таблицы соединяется с каждой строкой правой таблицы.

⚠️ Появилось начиная с версии 2.0. В более ранних версиях необходимо использовать INNER JOIN с тождественно равным истине.

SELECT A.A AS AA, A.B AS AB, A.C AS AC, B.A AS BA, B.B AS BB, B.D AS BD
FROM A CROSS JOIN B

Эквивалентно неявному соединению:

SELECT A.A AS AA, A.B AS AB, A.C AS AC, B.A AS BA, B.B AS BB, B.D AS BD
FROM A, B

В ранних версиях:

SELECT A.A AS AA, A.B AS AB, A.C AS AC, B.A AS BA, B.B AS BB, B.D AS BD
FROM A INNER JOIN B ON 1 = 1

Результат:

AAABACBABBBD
111103
111224
222103
222224

<named_columns_join>

Является упрощенной записью JOIN#<qualified_join> для случая когда содержит только сравнения на равенство и только одноименных столбцов. Часто встречается при соединению по внешнему ключу.

⚠️ Появилось начиная с версии 2.1

⚠️ Столбцы, которые учавствуют в USING в результирующем наборе встречаются по одному разу.

Также как JOIN#<qualified_join> разделяется на 4 типа.

SELECT *
FROM A RIGHT JOIN B USING(A, B)

Эквивалентно:

SELECT COALESCE(A.A, B.A) AS A, COALESCE(A.B, B.B) AS B, A.C, B.D
FROM A RIGHT JOIN B ON A.A = B.A AND A.B = B.B

Результат:

ABCD
10NULL3
2224

<natural_join>

Является упрощенной записью JOIN#<named_columns_join> для случая когда содержит все одноименные столбцы. Удобно при соединению по внешнему ключу.

⚠️ Появилось начиная с версии 2.1

⚠️ В отличии от других СУБД в Firebird <natural_join> соединяет именно по одноименным столбцам, а не по внешнему ключу.

SELECT *
FROM A NATURAL RIGHT JOIN B

Результат:

ABCD
10NULL3
2224

См. также

SELECT

http://www.ibase.ru/devinfo/joins.htm

Источник

http://www.firebirdsql.org/rlsnotesh/rlsnotes20.html#dml-dsql-cross-join

http://www.firebirdsql.org/rlsnotesh/rlsnotes210.html#rnfb210-joins-sntx

Обсуждение