| Принцип оператора JOIN в картинках |
|
В статті розглянуті принципи об'єднання таблиць і, для наочності, вони зображені на кругових діаграмах Попередження: в статті в умові об'єднання таблиць використовується як ON, так і USING, для різноманітності. Нагадую, що якщо стовпчики, по яких відбувається об'єднання, мають однакові імена, то необхідно використовувати USING (`ім'я_стовпчика`), в іншому випадку використовується ON `TableA`.`ім'я_стовпчика_з_TableA` = `TableB`.`ім'я_стовпчика_з_TableB`
Отже, припустімо, що в нас є два столи. Стіл А (TableA) зліва, та стіл Б (TableB) справа. Ми заселимо кожен чотирма персонажами, імена яких можуть бути присутні на обох столах.
В СУБД MySQL існують наступні оператори об'єднання:
INNER JOIN — INNER JOIN здійснює вибірку записів, які лише існують в TableA і TableB одночасно. Запит: SELECT * FROM `TableA` 2.INNER JOIN `TableB` 3.ON `TableA`.`name` = `TableB`.`name`
Ідентичний запит: SELECT * FROM `TableA`,`TableB`
WHERE `TableA`.`name` = `TableB`.`name` Результат:
LEFT JOINLEFT OUTER JOIN (LEFT JOIN) вказує, що ліва таблиця, керівна (в нашому випадку TableA) і здійснює по ній повну вибірку, здійснюючи пошук відповідних записів в таблиці TableB. Якщо відповідностей не знайдено, то СУБД поверне порожній показник - NULL. Вказівка OUTER - не обов'язково. Запит: SELECT * FROM `TableA`
LEFT JOIN `TableB` ON `TableA`.`name` = `TableB`.`name` Результат:
Щоб здійснити вибірку записів з таблиці TableA, яких не існує в таблиці TableB, ми виконуємо LEFT JOIN, але після цього з результату виключаємо записи, які не хочемо бачити, шляхом вказівки, що TableB.id являється нулем (вказуючи, що запис відсутній у таблиці TableB). Запит: SELECT * FROM `TableA`
LEFT JOIN `TableB` ON `TableA`.`name` = `TableB`.`name` WHERE `TableB`.`id` IS NULL Результат:
RIGHT JOIN RIGHT JOIN виконує ті ж функції, що й LEFT JOIN, за винятком того, що права таблиця буде прочитана першою. Таким чином, якщо в запитах з попереднього розділу LEFT замінити на RIGHT, то таблиця результатів, грубо кажучи, відлобразиться по вертикалі. Тобто, в результаті замість значень TableA будуть записи TableB і навпаки.
NATURAL JOIN Суть цієї конструкції в тому, що СУБД сама вибирає, по яких стовпчиках порівнювати та об'єднувати таблиці. А вибір цей падає на стовпчики з однаковими іменами. В цьому криється засада — СУБД може вибрати зовсім не ті стовпчики для об'єднання і запит буде працювати зовсім не так як ви розраховували. Запит: SELECT * FROM `TableA`
NATURAL JOIN `TableB` В цьому випадку СУБД вибирає для об'єднання таблиць стовпчики id і name, так як вони присутні в обох таблицях і перетворює початковий запит в запит наступного виду: SELECT * FROM `TableA`
INNER JOIN `TableB` USING (`id`, `name`) Але так як у нас немає записів з однаковим id і name одночасно в обох таблицях, то запит поверне порожній результат. SELECT `TableA`.*, `TableB`.* FROM `TableA`
NATURAL LEFT JOIN `TableB` Такий запит приводиться СУБД до наступного: SELECT `TableA`.*, `TableB`.* FROM `TableA`
LEFT JOIN `TableB` USING (`id`, `name`) То результат буде таким:
Відбувається це так: так як ліва таблиця керівна, то вона читається першою і повністю вибирається, незалежно від правої таблиці; коли починається пошук відповідних записів в правій таблиці, то СУБД не знаходить жодного запису, який був би ідентичним name і id одночасно, тому повертаються порожні показники. Для детального розуміння роботи NATURAL JOIN змінимо name в першому записі в таблиці TableB на Pirate. UPDATE `TableB` SET `name`='Pirate' WHERE `id`=1
Таким чином у нас вийшло:
Запит: SELECT * FROM `TableA`
NATURAL JOIN `TableB` Результат:
Так як тепер запис з одинаковим id і name присутній в обох таблицях, то він і буде виведений. Запит: SELECT `TableA`.*, `TableB`.* FROM `TableA`
NATURAL LEFT JOIN `TableB` Повертає результат:
Таким чином, СУБД сама вибирає по яких стовпчиках і яким способом об'єднувати таблиці. З одного боку це доволі зручно, з іншого — несе нерозбериху: де гарантія того, що стовпчики з однаковими іменами в в таблицях будуть саме ключовими і призначені для об'єднання? NATURAL JOIN погіршує читабельність коду, так як розробник не зможе за запитом визначити, як об'єднуються таблиці. Тому, звертаючи увагу на такі фактори, NATURAL JOIN використовувати не рекомендується.
STRAIGHT JOIN STRAIGHT JOIN виконує ті ж функції, що й звичайний INNER JOIN, за винятком того що ліва таблиця читається раніше правої. Запит: SELECT * FROM `TableA`
STRAIGHT JOIN `TableB` USING(`name`) Поверне результат:
Запит: SELECT * FROM `TableB`
STRAIGHT JOIN `TableA` USING(`name`) Поверне результат:
Декартова вибіркаЯкщо при об'єднанні таблиць не вказати умову об'єднання через ON або USING, то СУБД здійснить так звану Декартову вибірку, коли значенню однієї таблиці прирівнюється кожне значення іншої. Таким чином, СУБД, в нашому випадку, повертає 4x4 = 16 рядків. Запит: SELECT * FROM `TableA`
JOIN `TableB` Результат:
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
При розробці веб-проектів з використанням бази даних нам часто потрібно в запитах об'єднувати таблиці бази, щоб отримати необхідні дані.

