Перейти к содержимому

Реферальная программа Мегаплана

Партнерская программа Kredov

JOIN и UNION

#1 gaaarfild

gaaarfild
  • Пользователь
  • 596 сообщений
  • Репутация: 0
0

Отправлено 08 Декабрь 2009 - 12:17

Хотелось бы получить более доступную информацию по данным конструкциям.
Во всех мануалах написано сухо и очень недоступно.
Хотелось бы получить более доступно данную информацию.

 

 

  • 0

#2 ZiTosS

ZiTosS
  • Пользователь
  • 5 148 сообщений
  • Репутация: 8

Отправлено 09 Декабрь 2009 - 16:04

gaaarfild, ну попробуем-с....

JOIN
Оператор JOIN используется для объединения таблиц в запросах по определённому связывающему условию(признаку). В SQL-запросе данный оператор располагается между именами объединяемых таблиц после ключевого слова FROM. Ключевое слово JOIN имеет два синонима: CROSS JOIN и INNER JOIN.

Например у нас есть таблица АВТОМОБИЛИ (auto) с полями
(
id - уникальный номер(дескриптор) автомобиля
id_marka - идентификатор марки в таблице МАРКИ
id_owner - идентификатор владельца в таблице ВЛАДЕЛЬЦЫ
id_type - идентификатор типа автомобиля в таблице ТИПЫ
color - цвет автомобиля
description - описание автомобиля
)

Таблица МАРКИ (marks) с полями
(
id - уникальный номер(дескриптор) марки
marka - название марки
)

Таблица ВЛАДЕЛЬЦЫ (owners) с полями
(
id - уникальный номер(дескриптор) владельца
fio - ФИО владельца
passport - номер паспорта
и т.д. (нам не важно)
)

Таблица ТИПЫ (types) с полями
(
id - уникальный номер(дескриптор) типа
type - название типа
)

И мы хотим получить в запросе сразу все автомобили с ФИО владельца, типом автомобиля и марки автомобиля
Для этого мы будем в запросе использовать объединение таблиц с оператором JOIN
SELECT t1.id, t1.color, t1.description, t2.marka, t3.fio, t4.type FROM auto t1 JOIN marks t2, owners t3, types t4 ON t1.id_marka=t2.id AND t1.id_owner=t3.id AND t1.id_type=t4.id

И в сформированной нашим запросом представлении(с которой мы работаем как с ресурсом) будут такие поля:

id - уникальный номер(дескриптор) автомобиля в таблице АВТОМОБИЛИ
color - цвет автомобиля в таблице АВТОМОБИЛИ
description - описание автомобиля в таблице АВТОМОБИЛИ
marka - название марки в таблице МАРКИ
fio - ФИО владельца в таблице ВЛАДЕЛЬЦЫ
type - название типа в таблице ТИПЫ

Замечание
Использование в запросах оператора JOIN идентично использования перекрёстных запросов, т.е. пример выше можно было бы переписать так:
SELECT t1.id, t1.color, t1.description, t2.marka, t3.fio, t4.type FROM auto t1, marks t2, owners t3, types t4 WHERE t1.id_marka=t2.id AND t1.id_owner=t3.id AND t1.id_type=t4.id

Мы просто убрали ключевое слово JOIN и заменили ON => WHERE

Тут надо понимать, что оператор JOIN и перекрестные запросы применяют тогда, когда нужно полное соответствие данных главной таблицы и связанных таблиц. То есть к примеру у нас есть связь 1=1(один к одному), что означает наличие 2 таблиц связанных по определённому полю так, что каждой записи "первой таблице" соответствует одна запись в "правой таблице". При запросе вышеуказанными способами из результирующей таблицы будут исключены записи не нашедшие соответствия друг с другом (например в одной номер присутствует, а в другой нет).

На самом деле вся прелесть оператора JOIN раскрывается в применении других вариантов связывания - LEFT JOIN и RIGHT JOIN

LEFT JOIN
Левое объединение (LEFT JOIN) позволяет включить в результирующую таблицу строки "левой" таблицы, которым не нашлось соответствия в "правой" таблице.
Рассмотрим пример:
У нас есть таблица ДАТЫ (dates) - "левая" с полями
(
id - уникальный номер(дескриптор) даты
id_holiday - номер праздника в таблице ПРАЗДНИКИ (если дата не содержит праздника, то данное поле NULL или 0)
date - дата
)

таблица ПРАЗДНИКИ (holidays) - "правая" с полями
(
id - уникальный номер(дескриптор) праздника
name - название праздника
)

И вот нам захотелось посмотреть список всех дат не зависимо есть ли праздник в этот день или нет, но если есть, то хотим вывести его название. Становится понятным что если мы будем использовать оператор JOIN, то в результирующую таблицу не попадут даты, в которых отсутствует праздник, а нам бы этого не хотелось. И тут к нам на помощь приходит оператор LEFT JOIN:
SELECT t1.id, t1.date, t2.name FROM dates t1 LEFT JOIN holidays t2 ON t1.id_holiday=t2.id

В результирующей таблице будут все даты и в каждой записи обязательно будет присутствовать поле name (название праздника), но в тех записях где MySQL не нашла соответствий из "правой таблицы", поле name будет иметь значение NULL

RIGHT JOIN
Правое объединение (RIGHT JOIN) позволяет включить в результирующую таблицу строки "правой" таблицы, которым не нашлось соответствия в "левой" таблице.
То есть обратное соответствие относительно LEFT JOIN. Пример рассматривать не буду. Примерно всё тоже самое.


UNION
Если формат результирующих таблиц (число, порядок следования и тип столбцов) совпадает, то возможно объединение результатов выполнения двух операторов SELECT в одну результирующую таблицу. Это достигается с использованием оператора UNION
Например у нас есть таблица ПОЛЬЗОВАТЕЛИ (users) с полями:
(
id_user - уникальный номер (дескриптор) пользователя
fio - ФИО пользователя
)

И в этой таблице имеются 3 записи:
1 | Пупкин ВВ
2 | Сидоров АС
3 | Петров МА

И нам захотелось удвоить записи в таблице, для этого мы выполним обычный запрос SELECT и добавим к нему в конец запрос SELECT с id_user сдвинутыми на текущее количество пользователей (у нас 3)
SELECT id_user, fio FROM users
UNION
SELECT id_user + 3, fio FROM users

И в результирующей таблице мы получим:
1 | Пупкин ВВ
2 | Сидоров АС
3 | Петров МА
4 | Пупкин ВВ
5 | Сидоров АС
6 | Петров МА

Пример 2:
У нас есть 2 таблицы с идентичными по типу и следованию полями, но разные таблицы + разные имена полей. Мы хотим объединить эти 2 таблицы не прибегая к созданию двух результирующих таблиц:
SELECT * FROM table1
UNION
SELECT * FROM table2


Я думаю, стало яснее :)
  • 0

#3 surfer

surfer
  • Заблокированные
  • 1 956 сообщений
  • Репутация: 71

Отправлено 23 Январь 2010 - 23:50

Визуальное объяснение различных MySQL JOIN

MySQL JOIN — это мощнейший инструмент. Но в силу своей интуитивной непонятности он немного пугает новичков, которые начинают городить трехэтажные запросы, когда все можно сделать намного изящнее. По ссылке приведено визуальное объяснение, как работают INNER JOIN, FULL OUTER JOIN, LEFT OUTER JOIN и т.д.

http://www.codinghor...ves/000976.html
не могу нпайти перевод этой статьи
  • 0

#4 ZiTosS

ZiTosS
  • Пользователь
  • 5 148 сообщений
  • Репутация: 8

Отправлено 25 Январь 2010 - 01:34

sc2r2bey, А зачем тебе, там же к каждому запросу - картинка. Переводить-то нечего.

P.s.: Дельный урок. Прям как диаграммы Эйлера :)
  • 0

#5 surfer

surfer
  • Заблокированные
  • 1 956 сообщений
  • Репутация: 71

Отправлено 25 Январь 2010 - 02:00

я ж не себе а автору топика
  • 0

#6 ZiTosS

ZiTosS
  • Пользователь
  • 5 148 сообщений
  • Репутация: 8

Отправлено 25 Январь 2010 - 02:23

sc2r2bey, я не думаю, что ТС будет сложно разобратьсмя с парой картинок и парой запросов. Там всё соотнесено. Причём ТС я знаю :)
  • 0

#7 gaaarfild

gaaarfild
    Topic Starter
  • Пользователь
  • 596 сообщений
  • Репутация: 0

Отправлено 25 Январь 2010 - 03:17

Как всегда замечательное объяснение. Спасибо! =) Будем практиковать.
  • 0


Оформление форума – IPBSkins.ru