Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей.
Здесь обсуждаются безопасность, программирование, технологии и многое другое.
Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
 |
Sql. Явные операции соединения. Как готовить и с чем есть. |

03.05.2008, 00:48
|
|
Участник форума
Регистрация: 01.02.2007
Сообщений: 286
Провел на форуме: 804931
Репутация:
526
|
|
Sql. Явные операции соединения. Как готовить и с чем есть.
sql. Явные операции соединения. Как готовить и с чем есть.Содержание: - Типы соединений
- Перекрестное соединение
- Естественное соединение
- Соединение объединения
- Соединение посредством предиката
- Соединение посредством имен столбцов
- Примеры
- INNER JOIN
- LEFT JOIN
- RIGHT JOIN
- FULL JOIN
- UNION JOIN
ВведениеНаписать эту статью меня сподвиг следующий факт: очень многие не знают как применять JOIN'ы, а если и применяют — то в многих случаях не рационально, а то и неправильно (ведь в неумелых руках не так то и сложно завалить сервер, если таблицы достаточно большие). Хотя сама по себе тема не очень сложная. В разных СУБД разный уровень поддержки этих операций. Например PostgreSQL (что и неудивительно, ведь эта СУБД — университетская разработка, и наиболее близка к стандартам ANSI SQL... даже домены держит) поддерживает естественное соединение (чего нельзя сказать о MSSQL, по крайней мере 2005... до 2008 руки еще не дошли посмотреть, но в кратком обзоре я не встретил ничего про поддержку). Поэтому отойдем от конкретных СУБД и рассмотрим то, о чем гласит стандарт =) Впервые явные операции соединения появились в стандарте SQL2 (1992 год). До этого приходилось идти обходными путями, например так:
Код:
SELECT * FROM A, B WHERE A.col = B.col
Но соединением это нельзя назвать даже с натяжкой... И присутствовали следующие недостатки:- Здесь идет декартово произведение (т.е. комбинации всех строк одной таблицы, со всеми строками другой таблицы) — а потом накладывается ограничение (предикат в WHERE). Т.е. нагрузка неслабая. Допустим у нас 2 таблички: в одной 1000 строк, в другой 10000 строк. В итоге будет сформировано 1000*10000 = 10000000 строк а потом отобраны нужные нам. Видно что не самый лучший подход.
- Таким образом можно было реализовать не все типы и виды соединений, которые возможно реализовать с помощью явных операций соединения.
Но с появлением этих операций в стандарте, ситуация улучшилось. Рассмотрим что же там такого было.
Типы соединенийВсе типы соединений будут рассмотрены на 2-х таблицах: назовем их A и B. Весь запрос буду опускать, буду писать только то, что идет после FROM.
Код:
Таблица A:
-------------------------------------------------
| a | b | c |
-------------------------------------------------
| 1 | 1 | 1 |
-------------------------------------------------
| 1 | 2 | 1 |
-------------------------------------------------
| 2 | 1 | 1 |
-------------------------------------------------
| 2 | 2 | 2 |
-------------------------------------------------
Таблица B:
-------------------------------------------------
| a | b | d |
-------------------------------------------------
| 2 | 1 | 1 |
-------------------------------------------------
| 2 | 2 | 1 |
-------------------------------------------------
| 2 | 2 | 2 |
-------------------------------------------------
1. Перекрестное соединениеПо сути это то же декартово произведение... Было введено думаю только для удобства и читаемости  2. Естественное соединение
Код:
... A [Natural][<вид соединения>] JOIN B
Естественное соединение означает операцию соединения по всем столбцам с совпадающими именами, находящихся в соединяемых таблицах. Т.е. на выходе будут только те строки, в которых значения всех столбцов с совпадающими именами совпадают попарно.
Разумеется, столбцы с одинаковыми именами должны быть определены на совместимых типах данных.
Код:
Результат:
-----------------------------------------------------------------
| a | b | c | d |
-----------------------------------------------------------------
| 2 | 1 | 1 | 1 |
-----------------------------------------------------------------
| 2 | 2 | 2 | 1 |
-----------------------------------------------------------------
| 2 | 2 | 2 | 2 |
-----------------------------------------------------------------
3. Соединение объединенияДля читающих по диагонали или для тех кто не понял: соединение UNION и оператор UNION — это абсолютно разные понятия 
Пример будет ниже. 4. Соединение посредством предиката
Код:
... A [<вид соединения>] JOIN B ON <предикат>
Думаю все знают что предикат? Если нет — вот небольшое определение:
Предикат (n-местный, или n-арный) — это функция с областью значений {0,1} (или «Истина» и «Ложь»).
Если все равно не понятно — ну что ж...
http://ru.wikipedia.org/wiki/Предикат
Код:
A JOIN B ON A.a <> B.d
-------------------------------------------------------------------------------------------------
| a | A.b | A.c | B.a | B.b | d |
-------------------------------------------------------------------------------------------------
| 1 | 1 | 1 | 2 | 2 | 2 |
-------------------------------------------------------------------------------------------------
| 1 | 2 | 1 | 2 | 2 | 2 |
-------------------------------------------------------------------------------------------------
| 2 | 1 | 1 | 2 | 1 | 1 |
-------------------------------------------------------------------------------------------------
| 2 | 1 | 1 | 2 | 2 | 1 |
-------------------------------------------------------------------------------------------------
| 2 | 2 | 2 | 2 | 1 | 1 |
-------------------------------------------------------------------------------------------------
| 2 | 2 | 2 | 2 | 2 | 1 |
-------------------------------------------------------------------------------------------------
5. Соединение посредством имен столбцов
Код:
... A[<вид соединения>] JOIN B USING (<список столбцов>)
Где в списке столбцов указываются имена столбцов, по которым ведется соединение, через запятую 
Выше во многих типах соединения использовался <вид соединения>... Что ж это за зверь такой? А это на самом деле вот что:
Код:
<вид соединения> ::= INNER |{{LEFT|RIGHT|FULL}[OUTER]}
Ключевое слово OUTER (т.е. внешнее) не является обязательным и опять таки сделано для удобства.
Это соединение позволяет ограничить естественное соединение только теми столбцами с одинаковыми именами, которые нам необходимы. ПримерыПримеры будем рассматривать на двух следующих таблицах:
Код:
Таблица A:
-----------------------------------------
| id | nick |
-----------------------------------------
| 1 | VDShark |
-----------------------------------------
| 2 | Helios |
-----------------------------------------
| 3 | ArdeOS |
-----------------------------------------
Таблица B:
---------------------------------
| nick | contact |
---------------------------------
| VDShark | 55555 |
---------------------------------
| Helios | 77777 |
---------------------------------
| Helios | 88888 |
---------------------------------
| Mobile | 44444 |
---------------------------------
Это у нас допустим база людей, состоящая из 2-х таблиц: таблица с никами и таблица с контактами.
Судя по таблице ArdeOS скрывается, а Helios мажор — у него несколько контактов  1. A INNER JOIN B
Код:
---------------------------------------------------------
| id | nick | contact |
---------------------------------------------------------
| 1 | VDShark | 55555 |
---------------------------------------------------------
| 2 | Helios | 77777 |
---------------------------------------------------------
| 2 | Helios | 88888 |
---------------------------------------------------------
2. A LEFT JOIN B Левое соединение включает в себя все строки таблицы A (таблицы, записанной слева от JOIN) + совпадающие значения из таблицы B. Для строк из таблицы A, которым не нашлось совпадения в таблице B в столбцах из таблицы B помещаются NULL-значения
Код:
---------------------------------------------------------
| id | nick | contact |
---------------------------------------------------------
| 1 | VDShark | 55555 |
---------------------------------------------------------
| 2 | Helios | 77777 |
---------------------------------------------------------
| 2 | Helios | 88888 |
---------------------------------------------------------
| 3 | ArdeOS | NULL |
---------------------------------------------------------
3. A RIGHT JOIN B Правое соединение обратно левому, т.е. все столбцы из таблицы B (справа от JOIN) и те строки из таблицы A, для которых совпадают значения в одноименных столбцах.
Код:
---------------------------------------------------------
| id | nick | contact |
---------------------------------------------------------
| 1 | VDShark | 55555 |
---------------------------------------------------------
| 2 | Helios | 77777 |
---------------------------------------------------------
| 2 | Helios | 88888 |
---------------------------------------------------------
| NULL | Mobile | 44444 |
---------------------------------------------------------
4. A FULL JOIN B Это объединение левого и правого соединения. Присутствуют все строки из обеих таблиц. Если строки совпадают по столбцам — то они заполнены, если же нет — то в отсутствующие заносятся NULL-значения.
Код:
---------------------------------------------------------
| id | nick | contact |
---------------------------------------------------------
| 1 | VDShark | 55555 |
---------------------------------------------------------
| 2 | Helios | 77777 |
---------------------------------------------------------
| 2 | Helios | 88888 |
---------------------------------------------------------
| 3 | ArdeOS | NULL |
---------------------------------------------------------
| NULL | Mobile | 44444 |
---------------------------------------------------------
5. A UNION JOIN B Это соединение является обратным по отношению к INNER, т.е. включает только те строки, для которых не найдено совпадений.
Код:
---------------------------------------------------------
| id | nick | contact |
---------------------------------------------------------
| 3 | ArdeOS | NULL |
---------------------------------------------------------
| NULL | Mobile | 44444 |
---------------------------------------------------------
Вывод.Из вышесказанного видно: оказывается не так то оно и сложно. Главное иметь хоть немного усидчивости что бы разобраться.
|
|
|

03.05.2008, 05:34
|
|
Leaders of Antichat - Level 4
Регистрация: 16.01.2006
Сообщений: 1,966
Провел на форуме: 21768337
Репутация:
3486
|
|
Не знаю насколько эта статья полезней манулов в книгах/на сайтах, не знаю чем она поможет здешней аудитории которая только подставляет кавычки. Но оформлена хорошо.
|
|
|
|
 |
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
|
|
|
|