Добавить в избранное   Сделать стартовой   Главная   E-mail   Форум   Мой блог 
   
Cертификации

Errors

ETL

FAQ (по темам)

GIS

Web

wiki

Администрирование

Безопасность

Книги
Oracle, ...

Новости

ОС

Программирование

Проектирование БД

Производительность

Скачать

Советы

Тестирование

Установка

FAQ - по базам данных
FAQ - по базам данных
Установка СУБД
Oracle
Sybase
MySQL
PostgreSQL
MS SQL Server
Interbase, Firebird
Другие DB
Администрирование
Oracle
MySQL
Sybase
PostgreSQL
MS SQL Server
Interbase, Firebird
IBM DB2
Другие DB
Проектирование БД
Статьи
ETL
Теория БД
ErWin
Designer 2000
PowerDesigner
Хранилища данных
CASE средства
OLAP
Бизнес - анализ (BI)
Производительность
Oracle
MSSQL
Interbase, Firebird
IBM DB2
MySQL
PostgreSQL
SYBASE
Безопасность БД
Oracle
MS SQL Server
Инъекция SQL
Программирование
Transact-SQL
PL/SQL
C++
XML
SQL
PostgreSQL
MDX
Java
VBA Excel
Книги по базам
Oracle
Заказ книг
ОС
Установка и настройка
UBUNTU
ОС
Установка и настройка
UBUNTU
FAQ
FAQ - по базам данных
Главная arrow SQL arrow Для чего вообще нужен оператор JOIN?

Для чего вообще нужен оператор JOIN?

Печать E-mail

Для чего вообще нужен оператор JOIN?

 Раздел JOIN используется для связывания данных двух таблиц между собой. Но почему лучше использовать JOIN, чем простое перечисление таблиц в разделе FROM и перечисление условий присоединения с использованием операторов =, *=, =* и т.п. в разделе WHERE? Давайте разберемся.

Как правило, нормализованные распределенные базы данных строятся таким образом, что в них есть "главные таблицы", а к ним уже присоединяются несколько справочников по каким-нибудь специальным ID-полям или по нескольким простым полям. Сами же "главные таблицы" тоже могут являться справочниками для других таблиц.
Для начала создайте в тестовой базе таблицы с помощью следующего скрипта:

CREATE TABLE Master1

(

Master1ID int IDENTITY (1,1) NOT NULL,

Detail1ID int NULL,

Detail2ID int NULL,

Name varchar(200),

CONSTRAINT PK_Master1 PRIMARY KEY CLUSTERED

(Master1ID)

)

GO

CREATE TABLE Detail1

(

Detail1ID int IDENTITY (1,1) NOT NULL,

Name varchar(200),

CONSTRAINT PK_Detail1 PRIMARY KEY CLUSTERED

(Detail1ID)

)

GO

CREATE TABLE Detail2

(

Detail2ID int IDENTITY (1,1) NOT NULL,

Name varchar(200),

CONSTRAINT PK_Detail2 PRIMARY KEY CLUSTERED

(Detail2ID)

)

GO

insert Detail1 (Name) values('1')

insert Detail1 (Name) values('2')

insert Detail1 (Name) values('3')

insert Detail1 (Name) values('4')

GO

insert Detail2 (Name) values('d1')

insert Detail2 (Name) values('d2')

insert Detail2 (Name) values('d3')

insert Detail2 (Name) values('d4')

GO

insert Master1 (Detail1ID,Detail2ID,Name) values(1,1,'1')

insert Master1 (Detail1ID,Detail2ID,Name) values(2,2,'2')

insert Master1 (Detail1ID,Detail2ID,Name) values(1,2,'3')

insert Master1 (Detail1ID,Detail2ID,Name) values(4,3,'1')

insert Master1 (Detail1ID,Detail2ID,Name) values(null,1,'n1')

insert Master1 (Detail1ID,Detail2ID,Name) values(3,null,'n2')

GO


С помощью JOIN-ов выборки из таких структур становятся читабельнее, быстрее и лучше разбираются оптимизатором и соответственно быстрее работают.

В секции ON пишется условие, по которому присоединяется таблица.


Без JOIN простая выборка будет следующей:

select a.Master1ID, a.Name, b.Name, c.Name

from Master1 a, Detail1 b, Detail2 c

where a.Detail1ID=b.Detail1ID

and a.Detail2ID=c.Detail2ID


С использованием JOIN эта же выборка:

select a.Master1ID, a.Name, b.Name, c.Name

from Master1 a

join Detail1 b on b.Detail1ID=a.Detail1ID-- одна строка - один присоединенный справочник

join Detail2 c on c.Detail2ID=a.Detail2ID


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

Краткий вид и полный вид:

join = inner join

left join = left outer join

full join = full outer join

cross join = указание таблиц через запятую в разделе from.

Причем чаще всего используются только первые два вида.


В нашем случае задача усложняется за счет пустых ключевых полей справочников. Т.е. хотелось бы получить все 6 строк. Вот две выборки - без JOIN и с ним:

select a.Master1ID, a.Name, b.Name, c.Name

from Master1 a, Detail1 b, Detail2 c

where a.Detail1ID*=b.Detail1ID

and a.Detail2ID*=c.Detail2ID



select a.Master1ID, a.Name, b.Name, c.Name

from Master1 a

left join Detail1 b on b.Detail1ID=a.Detail1ID

left join Detail2 c on c.Detail2ID=a.Detail2ID


Если Вы полностью уверены, что в главной таблице нет пустых ключевых полей, то лучше использовать JOIN без LEFT, т.к. такая конструкция работает быстрее.


Стоит немного усложнить задачу и конструкция без JOIN уже не поможет. Случай присоединения таблицы не по одному ключевому полю, а по двум и более. У нас это будет ID и Name. Попробуйте выполнить следующий скрипт:

select a.Master1ID, a.Name, b.Name, c.Name

from Master1 a, Detail1 b, Detail2 c

where a.Detail1ID*=b.Detail1ID and b.Name*=a.Name

and a.Detail2ID*=c.Detail2ID and c.Name*=a.Name



select a.Master1ID, a.Name, b.Name, c.Name

from Master1 a

left join Detail1 b on b.Detail1ID=a.Detail1ID and b.Name=a.Name

left join Detail2 c on c.Detail2ID=a.Detail2ID and c.Name=a.Name


Что и требовалось доказать. Без JOIN никуда.


Если нужно написать дополнительные условия, то их лучше помещать в разделе WHERE. Хотя если используется JOIN без LEFT, то нет никакой разницы, где писать условие - хочешь в секции ON, хочешь в разделе WHERE. Вот два идентичных запроса:

select a.Master1ID, a.Name, b.Name, c.Name

from Master1 a

join Detail1 b on b.Detail1ID=a.Detail1ID

join Detail2 c on c.Detail2ID=a.Detail2ID and a.Name='1'



select a.Master1ID, a.Name, b.Name, c.Name

from Master1 a

join Detail1 b on b.Detail1ID=a.Detail1ID

join Detail2 c on c.Detail2ID=a.Detail2ID

where a.Name='1'


И еще использовать JOIN удобнее, чем перечисление в разделе FROM тем, что в любой момент можно поставить LEFT и в результат запроса сразу будут включены все строки с пустым ключевым полем справочника.


А нижеследующий код без JOIN никак не воспроизвести:

select a.Master1ID, a.Name, b.Name, c.Name

from Master1 a

full join Detail1 b on b.Detail1ID=a.Detail1ID and b.Name=a.Name

full join Detail2 c on c.Detail2ID=a.Detail2ID and c.Name=a.Name

GO


CROSS JOIN больше относиться к теме "маньячества", когда условия на присоединение нет (чистое перемножение), а писать больше двух таблиц в секции FROM уже не хочется.


И еще. Иногда бывает разница в быстродействии при присоединении маленькой таблицы к большой и наоборот. Для оптимизации стоит поэкспериментировать.


На этом закончим. Удалить созданные объекты можно с помощью следующего кода:

DROP TABLE Master1

DROP TABLE Detail1

DROP TABLE Detail2

GO


 
 
« Пред.   След. »
Взаимосвязанные статьи
     

Последние добавленные статьи
Поиск
Ссылки
Главная
Скачать
Курсы
Роль АБД (SYSDBA)
Карта сайта
Автостекла
Контакты
Войти на сайт
Популярные статьи
Online - тесты
1Z0-042
Rambler's Top100 МЕТА - Украина. Рейтинг сайтов хостинг от freehost.com.ua

Все права защищены.SYSDBA 2010 | Если у Вас есть хороший материал пришлите его нам.