Галерея
7757 8119 8300 8698 8817 9504 9722 9937
Интересные записи
Топовые новости
Новое

Предложение JOIN советы и хитрости программирования

Если тип_соединения явно не указан, то подразумевается INNER JOIN. Обратите внимание, что существует много типов соединений, каждый из которых имеет свои правила и функциональность, описанные в разделе «Общие правила».

Как правило, при описании соединений следует предпочитать предложение JOIN предложению WHERE. Это не только делает код более понятным и позволяет отличать условия соединения от условий поиска, но также позволяет избегать ошибок, связанных с реализациями внешних соединений с помощью предложений WHERE на некоторых платформах.

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

Не все платформы поддерживают все типы соединений, так что обращайтесь к описанию платформо-специфической поддержки соединений в соответствующих разделах.

Платформа DB2 поддерживает соединения INNER и OUTER с использованием предложения ON. Не поддерживаются синтаксические конструкции NATURAL и CROSS, а также USING. Синтаксис предложения JOIN в DB2 выглядит следующим образом.

Соединения, включающие более двух таблиц, могут быть весьма сложными. Если в соединении участвует три и более таблицы, лучше подумать о создании запроса, представляющего собой серию двухтабличных соединений.


MySQL

Платформа MySQL поддерживает большую часть синтаксиса ANSI, за исключением того, что соединения с префиксом NATURAL поддерживаются только для внешних, но не для внутренних соединений. Синтаксис предложения JOIN в MySQL следующий.

FROM таблица [AS псевдоним] {[STRAIGHT_JOIN соединяемая_таблица] | {{[INNER] | |

[CROSS] | [NATURAL] [{LEFT | RIGHT | FULL} [OUTER]]} JOIN соединяемая_таблица [AS псевдоним]

{ON условие_соединения1 [{AND|OR} условие_соединения2] […]] | USING (столбец1 [, …])}}} […]

Где:

STRAIGHT JOIN

Заставляет оптимизатор соединять таблицы в том порядке, как они упоминаются в предложении FROM.

Ключевое слово STRAIGHTJOIN функционально эквивалентно слову JOIN, за исключением того, что соединения принудительно выполняются в порядке слева направо. Эта опция нужна, потому что MySQL может, хотя и редко, соединять таблицы в неверном порядке.


Oracle

Платформа Oracle полностью поддерживает стандартный синтаксис ANSI для предложения JOIN. Однако в Oracle поддержка синтаксиса ANSI появилась, только начиная с версии 9. Соответственно в более старом коде Oracle используются исключительно соединения с предложением WHERE. В старом синтаксисе Oracle для внешних тета-соединений поддерживалось добавление знака + к именам столбцов на стороне, противоположной внешней таблице. Старый синтаксис внешних тета-соединений в Oracle исходит из того факта, что в таблицу, поставляющую строки с пустыми значениями, эти строки были добавлены. Платформа Oracle отражает этот факт, добавляя «+» к имени столбца на стороне, противоположной направлению соединения.

Например, в следующем запросе производится соединение RIGHT OUTER JOIN таблиц authors и publishers. Старый синтаксис Oracle будет выглядеть следующим образом.

SELECT
a.au_lname AS ‘first name’,
a.au_fname AS ‘last name’,
p.pub_name AS ‘publisher’
FROM authors a, publishers p
WHERE a.city(+)=p.city
ORDER BY a.au_lname DESC;

Тот же самый запрос, написанный с использованием синтаксиса ANSI, будет выглядеть так.

SELECT
a.au_lname AS ‘first name’,
a.au_fname AS ‘last name’,
p.pub_name AS ‘publisher’
FROM authors AS a
RIGHT OUTER JOIN publishers AS p ON a.city=p.city
ORDER BY a.au_lname DESC;

Дополнительные примеры с использованием предложения JOIN приведены в разделе «Общие правила».

Платформа Oracle — единственная, которая позволяет использовать секционированные внешние соединения (partitioned outer joins), которые полезны для заполнения пустых мест в результирующих наборах, возникающих из-за фрагментированного хранения данных. Например, предположим, что записи о продукции хранятся в таблице manufacturing с двумя ключами — день и идентификатор продукта. В таблице хранятся записи, показывающие количество произведенного продукта в любой день, когда продукция производилась, но отсутствуют строки, соответствующие дням, когда продукция не производилась. Такая структура считается фрагментированной, поскольку в списке строк не отражены все дни и все продукты. Для проведения расчетов и создания отчетов хорошо бы создать такой набор данных, в котором производство каждого продукта было бы отражено по всем дням, независимо от того, производился продукт или нет. Это можно просто сделать при помощи секционированного внешнего соединения, поскольку оно позволяет определить логический раздел и применить внешнее соединение к каждому значению этого раздела. Ниже приводится пример с таблицей manufacturing, которая соединяется при помощи внешнего секционированного соединения с таблицей times, чтобы создать для каждого значения product_id полный набор дат в указанном диапазоне.

SELECT
times.time_id AS time,
product_id AS id,
quantity AS qty
FROM manufacturing
PARTITION BY (product_id)
RIGHT OUTER JOIN times ON (manufacturing.time_id=times.time_id)
WHERE manufacturing, time_id BETWEEN TO_DATE(’01/10/05′, ‘DD/MM/YY’) AND TO_DATE(’06/10/05′, ‘DD/MM/YY’)
ORDER BY 2, 1;

Чтобы получить такой же результат без использования секционированного внешнего соединения, нужно писать более сложный и менее эффективный код.


PostgreSQL

Платформа PostgreSQL полностью поддерживает стандарт ANSI. Примеры приводятся в разделе «Общие правила».


SQL Server

Платформа SQL Server поддерживает соединения типов INNER, OUTER и CROSS с использованием предложения ON. SQL Server не поддерживает синтаксические конструкции NATURAL и USING. Синтаксис инструкции JOIN в SQL Server следующий.

FROM таблица [AS псевдоним]

{{[INNER] | | [CROSS] | [{LEFT | RIGHT | FULL} [OUTER]]} JOIN соединяемая_таблица [AS псевдоним]

{ON условие_соединения! [{AND|OR} условие_соединения2] […]]} […]

Примеры приведены в разделе «Общие правила».

Источник