Контакти

Mysql з'єднати дві таблиці

Що виконується раніше - JOIN або GROUP BY? Цей неявний питання не виникало у мене до тих пір, поки відповідь на нього не сплив у вигляді помилкових даних, що повертаються моїм запитом. Зрозуміло, JOIN виконується раніше, він і в запитах пишеться до GROUP BY. Але що, якщо мені потрібно об'єднати таблиці вже після угруповання? Розглянемо простий приклад, коли це може знадобитися.

Уявімо собі не дуже зручну, але дуже просту систему бухгалтерії, що складається з двох таблиць: Income - таблиця доходів і Outlay - таблиця витрат. В обох таблицях по 3 поля: id (INT), time (DATETIME), sum (INT):

# Income (доходи) # Outlay (витрати) id time sum id time sum 1 2014-01-01 00:00:00 100 1 2014-01-02 00:00:00 100 2 2014-01-01 23:59: 59 100 2 2014-01-02 23:59:59 100 3 2014-01-02 00:00:00 500

Як бачите, 1 січня у нас було дві продажу по 100 рублів, а 2 січня - продаж на 500 і два витрати по 100 рублів.

Об'єднуємо, агрегируя, групуємо

Уявімо, що перед нами стоїть завдання вивести таблицю щоденних доходів. Все просто, ми повинні скласти суми, виконавши угруповання за датою:

# Підсумовуємо доходи і групуємо їх по днях SELECT DATE ( `income`.`time`)` date`, SUM ( `income`.`sum`)` inSum` FROM `Income`` income` GROUP BY DATE ( `income` .`time`); # Результат виконання - сума доходів по днях date inSum 2014-01-01 200 2014-01-02 500

Ну а тепер навпаки кожної дати мені захотілося вивести суму витрат. І ось що я, наївний, написав:

# Об'єднуємо таблиці доходів і витрат за датою, підсумовуємо доходи і витрати, групуючи по днях # Так писати НЕ ТРЕБА: SELECT DATE ( `income`.`time`)` date`, SUM ( `income`.`sum`)` inSum `, SUM (` outlay`.`sum`) `outSum` FROM` Income` `income` LEFT JOIN` Outlay` `outlay` ON DATE (` income`.`time`) \u003d DATE ( `outlay`.`time `) GROUP BY DATE (` income`.`time`); # Ялинки-палиці! Прибуток на 2 січня збільшилася в 2 рази! date inSum outSum 2014-01-01 200 NULL 2014-01-02 1000 (!) 200

Як бачите, у відповіді повернувся абсолютний жах - доходи на 2 січня збільшилися в 2 рази. Як вже було зазначено на початку статті, JOIN виконується до GROUP BY, відповідно, через те, що 2 січня у нас було дві статті витрат, статті доходів продублювати при об'єднанні таблиць, що призвело до задвоєння доходів при підсумовуванні. Логіка підказує, що для виправлення проблеми ми повинні об'єднувати таблиці, вже згруповані по даті.

Рання угруповання при об'єднанні таблиць MySQL за допомогою вкладеного запиту

В межах одного запиту ми не можемо спершу згрупувати, а потім зв'язати таблиці, але ми можемо здійснити відкладене об'єднання з результатом вкладеного запиту, а угруповання виконати заздалегідь в ньому. Робиться це так:

# Заздалегідь групуємо дані в таблиці Outlay, потім виробляємо об'єднання з таблицею Income SELECT DATE ( `income`.`time`)` date`, SUM ( `income`.`sum`)` inSum`, `outlayGroupped`.`outSum` FROM `income`` income` LEFT JOIN (# Наш вкладений запит з угрупованням SELECT SUM ( `outlay`.`sum`)` outSum`, DATE ( `outlay`.`time`)` outDate` FROM `Outlay`` outlay `GROUP BY DATE (` outlay`.`time`)) `outlayGroupped` ON DATE (` income`.`time`) \u003d `outlayGroupped`.`outDate` GROUP BY DATE (` income`.`time`); # Прибутки звичайно менше, ніж минулого разу, але зате цифри правильні :) date inSum outSum 2014-01-01 200 NULL 2014-01-02 500 200

Зазвичай такі неявні проблеми вимагають настільки ж неявних рішень в двох випадках - коли не зовсім коректно поставлена \u200b\u200bзадача або коли архітектура проекту залишає бажати кращого. В даному випадку звичайно структура бази даних притягнута за вуха заради прикладу.

Ну і давайте не забувати, що вкладені запити - це завжди не є добре, адже вони виконуються окремо і незалежно від зовнішніх. Тому, працюючи з якоїсь великої статистикою, не забувайте їх оптимізувати і проставляти ліміти. А ще краще - подумайте над своєю :)

Оператор мови SQL JOIN призначений для з'єднання двох або більше таблиць бази даних по збігається умові. Цей оператор існує тільки в реляційних базах даних. Саме завдяки JOIN реляційні бази даних мають таку потужну функціональність, яка дозволяє вести не тільки зберігання даних, але і їх, хоча б найпростіший, аналіз за допомогою запитів. Розберемо основні нюанси написання SQL-запитів з оператором JOIN, які є загальними для всіх СУБД (систем управління базами даних). Для з'єднання двох таблиць оператор SQL JOIN має наступний синтаксис:

SELECT ІМЕНА_СТОЛБЦОВ (1..N) FROM ІМЯ_ТАБЛІЦИ_1 JOIN ІМЯ_ТАБЛІЦИ_2 ON УМОВА

Після одного або декількох ланок з оператором JOIN може слідувати необов'язкова секція WHERE або HAVING, в якій, також, як в простому SELECT-запиті, задається умова вибірки. Загальним для всіх СУБД є те, що в цій конструкції замість JOIN може бути зазначено INNER JOIN, LEFT OUTER JOIN, RIGHT OUTER JOIN, FULL OUTER JOIN, CROSS JOIN (або, як варіант, кома).

INNER JOIN (внутрішнє з'єднання)

Запит з оператором INNER JOIN призначений для з'єднання таблиць і виведення результуючої таблиці, в якій дані повністю перетинаються за умовою, вказаною після ON.

Те ж саме робить і просто JOIN. Таким чином, слово INNER - не обов'язкова.

Приклад 1. Є база даних порталу оголошень. У ній є таблиця Categories (категорії оголошень) і Parts (частини, або інакше - рубрики, які і відносяться до категорій). Наприклад, частини Квартири, Дачі відносяться до категорії Нерухомість, а частини Автомобілі, Мотоцикли - до категорії Транспорт. Ці таблиці з заповненими даними мають такий вигляд.

Таблиця Parts:

Зауважимо, що в таблиці Parts Книги мають Cat - посилання на категорію, якій немає в таблиці Categories, а в таблиці Categories Техніка має Cat_ID - первинний ключ, посилання на який немає в таблиці Parts. Потрібно з'єднати дані цих двох таблиць так, щоб в результуючій таблиці були поля Part (Частина), Cat (Категорія) і Price (Ціна подачі оголошення) і щоб дані повністю перетиналися за умовою. Умова - збіг ідентифікатора категорії в таблиці Categories і посилання на категорію в таблиці Parts. Для цього пишемо наступний запит:

SELECT PARTS.Part, CATEGORIES.Cat_ID AS Cat, CATEGORIES.Price FROM PARTS INNER JOIN CATEGORIES ON PARTS.Cat \u003d CATEGORIES.Cat_ID

PartCatPrice
квартири505 210,00
автомашини205 160,00
дошки10 105,00
Шафи30 77,00

У результуючій таблиці немає Книг, так як цей запис посилається на категорію, якій немає в таблиці Categories, і Техніки, так як цей запис має зовнішній ключ в таблиці Categories, на який немає посилання в таблиці Parts.

У ряді випадків при з'єднаннях таблиць скласти менш громіздкі запити можна за допомогою предиката EXISTS і без використання JOIN.

Є база даних "Театр". Таблиця Play містить дані про постановках. Таблиця Team - про ролі акторів. Таблиця Actor - про акторів. Таблиця Director - про режисерів. Поля таблиць, первинні та зовнішні ключі можна побачити на малюнку нижче (для збільшення натиснути лівою кнопкою миші).


Приклад 3. Вивести список акторів, які в одній виставі грають більше однієї ролі, і кількість їх ролей.

Оператор JOIN використовувати 1 раз. використовувати HAVING, GROUP BY .

Підказка. Оператор HAVING застосовується до числа ролей, підрахованих агрегатної функцією COUNT.

LEFT OUTER JOIN (ліве зовнішнє з'єднання)

Запит з оператором LEFT OUTER JOIN призначений для з'єднання таблиць і виведення результуючої таблиці, в якій дані повністю перетинаються за умовою, вказаною після ON, і доповнюються записами з першої по порядку (лівої) таблиці, навіть якщо вони не відповідають умові. У записів лівої таблиці, які не відповідають умові, значення стовпця з правої таблиці буде NULL (невизначеним).

Приклад 4. База даних і таблиці - ті ж, що і в прикладі 1.

Для отримання результуючої таблиці, в якій дані з двох таблиць повністю перетинаються за умовою і доповнюються усіма даними з таблиці Parts, які не відповідають умові, пишемо наступний запит:

SELECT PARTS.Part, CATEGORIES.Cat_ID AS Cat, CATEGORIES.Price FROM PARTS LEFT OUTER JOIN CATEGORIES ON PARTS.Cat \u003d CATEGORIES.Cat_ID

Результатом виконання запиту буде наступна таблиця:

PartCatPrice
квартири505 210,00
автомашини205 160,00
дошки10 105,00
Шафи30 77,00
книги160 NULL

В результуючої таблиці, на відміну від таблиці з прикладу 1, є Книги, але значення стовпця Ціни (Price) у них - NULL, так як цей запис має ідентифікатор категорії, якої немає в таблиці Categories.

RIGHT OUTER JOIN (праве зовнішнє з'єднання)

Запит з оператором RIGHT OUTER JOIN призначений для з'єднання таблиць і виведення результуючої таблиці, в якій дані повністю перетинаються за умовою, вказаною після ON, і доповнюються записами з другої по порядку (правої) таблиці, навіть якщо вони не відповідають умові. У записів правої таблиці, які не відповідають умові, значення стовпця з лівої таблиці буде NULL (невизначеним).

Приклад 5.

Для отримання результуючої таблиці, в якій дані з двох таблиць повністю перетинаються за умовою і доповнюються усіма даними з таблиці Categories, які не відповідають умові, пишемо наступний запит:

SELECT PARTS.Part, CATEGORIES.Cat_ID AS Cat, CATEGORIES.Price FROM PARTS RIGHT OUTER JOIN CATEGORIES ON PARTS.Cat \u003d CATEGORIES.Cat_ID

Результатом виконання запиту буде наступна таблиця:

PartCatPrice
квартири505 210,00
автомашини205 160,00
дошки10 105,00
Шафи30 77,00
NULL45 65,00

В результуючої таблиці, на відміну від таблиці з прикладу 1, є запис з категорією 45 і ціною 65,00, але значення стовпця Частини (Part) у неї - NULL, так як цей запис має ідентифікатор категорії, на яку немає посилань в таблиці Parts .

FULL OUTER JOIN (повне зовнішнє з'єднання)

Запит з оператором FULL OUTER JOIN призначений для з'єднання таблиць і виведення результуючої таблиці, в якій дані повністю перетинаються за умовою, вказаною після ON, і доповнюються записами з першої (лівої) і другий (правої) таблиць, навіть якщо вони не відповідають умові. У записів, які не відповідають умові, значення стовпців з іншої таблиці буде NULL (невизначеним).

Приклад 6. База даних і таблиці - ті ж, що і в попередніх прикладах.

Для отримання результуючої таблиці, в якій дані з двох таблиць повністю перетинаються за умовою і доповнюються усіма даними як з таблиці Parts, так і з таблиці Categories, які не відповідають умові, пишемо наступний запит:

SELECT PARTS.Part, CATEGORIES.Cat_ID AS Cat, CATEGORIES.Price FROM PARTS FULL OUTER JOIN CATEGORIES ON PARTS.Cat \u003d CATEGORIES.Cat_ID

Результатом виконання запиту буде наступна таблиця:

PartCatPrice
квартири505 210,00
автомашини205 160,00
дошки10 105,00
Шафи30 77,00
книги160 NULL
NULL45 65,00

У результуючій таблиці є записи Книги (з лівої таблиці) і з категорією 45 (з правої таблиці), причому у першій з них невизначена ціна (стовпець з правої таблиці), а у другій - невизначена частина (стовпець з лівої таблиці).

Псевдоніми з'єднуються таблиць

У попередніх запитах ми вказували з назвами видобутих стовпців з різних таблиць повні імена цих таблиць. Такі запити виглядають громіздко: одне і те ж слово повторюється кілька разів. Чи не можна якось спростити конструкцію? Виявляється, можна. Для цього слід використовувати псевдоніми таблиць - їх скорочені імена. Ім'я користувача може складатися і з однієї літери. Можливо будь-яку кількість букв в псевдонім, головне, щоб запит після скорочення був зрозумілий Вам самим. Загальне правило: в секції запиту, визначальною з'єднання, тобто навколо слова JOIN потрібно вказати повні імена таблиць, а за кожним ім'ям повинен слідувати псевдонім таблиці.

Приклад 7. Переписати запит з прикладу 1 з використанням псевдонімів з'єднуються таблиць.

Запит буде наступним:

SELECT P.Part, C.Cat_ID AS Cat, C.Price FROM PARTS P INNER JOIN CATEGORIES C ON P.Cat \u003d C.Cat_ID

Запит поверне те ж саме, що і запит в прикладі 1, але він набагато компактніше.

JOIN і з'єднання більше двох таблиць

Реляційні бази даних повинні підкорятися вимогам цілісності і ненадлишкових даних, в зв'язку з чим дані про один бізнес-процесі можуть міститися не тільки в одній, двох, але і в трьох і більше таблицях. У цих випадках для аналізу даних використовуються ланцюжки з'єднаних таблиць: наприклад, в одній (першої) таблиці міститься деякий кількісний показник, другу таблицю з першої і третьої пов'язують зовнішні ключі - дані перетинаються, але тільки третя таблиця містить умову, в залежності від якого може бути виведений кількісний показник з першої таблиці. І таблиць може бути ще більше. За допомогою оператора SQL JOIN в одному запиті можна поєднати велику кількість таблиць. У таких запитах за однією секцією з'єднання слід інша, причому кожен наступний JOIN з'єднує з наступною таблицею таблицю, яка була другою в попередньому ланці ланцюжка. Таким чином, синтаксис SQL запиту для з'єднання більше двох таблиць наступний:

SELECT ІМЕНА_СТОЛБЦОВ (1..N) FROM ІМЯ_ТАБЛІЦИ_1 JOIN ІМЯ_ТАБЛІЦИ_2 ON УМОВА JOIN ІМЯ_ТАБЛІЦИ_3 ON УМОВА ... JOIN ІМЯ_ТАБЛІЦИ_M ON УМОВА

Приклад 8. База даних - та ж, що і в попередніх прикладах. До таблиць Categories і Parts в цьому прикладі додасться таблиця Ads, яка містить дані про опубліковані на порталі оголошеннях. Наведемо фрагмент таблиці Ads, в якому серед записів є записи про тих оголошеннях, термін публікації яких закінчується 2018-04-02.

A_IdPart_IDDate_startDate_endText
21 1 "2018-02-11" "2018-04-20" "Продаю ..."
22 1 "2018-02-11" "2018-05-12" "Продаю ..."
... ... ... ... ...
27 1 "2018-02-11" "2018-04-02" "Продаю ..."
28 2 "2018-02-11" "2018-04-21" "Продаю ..."
29 2 "2018-02-11" "2018-04-02" "Продаю ..."
30 3 "2018-02-11" "2018-04-22" "Продаю ..."
31 4 "2018-02-11" "2018-05-02" "Продаю ..."
32 4 "2018-02-11" "2018-04-13" "Продаю ..."
33 3 "2018-02-11" "2018-04-12" "Продаю ..."
34 4 "2018-02-11" "2018-04-23" "Продаю ..."

Уявімо, що сьогодні "2018-04-02", тобто це значення приймає функція CURDATE () - поточна дата . Потрібно дізнатися, до яких категорій належать оголошення, термін публікації яких закінчується сьогодні. Назви категорій є тільки в таблиці CATEGORIES, а дати закінчення терміну публікації оголошень - тільки в таблиці ADS. У таблиці PARTS - частини категорій (або простіше, підкатегорії) опублікованих оголошень. Але зовнішнім ключем Cat_ID таблиця PARTS пов'язана з таблицею CATEGORIES, а таблиця ADS пов'язана зовнішнім ключем Part_ID з таблицею PARTS. Тому з'єднуємо в одному запиті три таблиці і цей запит можна з максимальною коректністю назвати ланцюжком.

Запит буде наступним:

Результат запиту - таблиця, яка містить назви двох категорій - "Нерухомість" і "Транспорт":

Cat_name
Нерухомість
транспорт

CROSS JOIN (перехресне з'єднання)

Використання оператора SQL CROSS JOIN в найбільш простій формі - без умови з'єднання - реалізує операцію декартова твори в реляційній алгебрі . Результатом такого з'єднання буде зчеплення кожного рядка першої таблиці з кожним рядком другої таблиці. Таблиці можуть бути записані в запиті або через оператор CROSS JOIN, або через кому між ними.

Приклад 9. База даних - все та ж, таблиці - Categories і Parts. Реалізувати операцію декартова твори цих двох таблиць.

Запит буде наступним:

SELECT (*) Categories CROSS JOIN Parts

Або без явної вказівки CROSS JOIN - через кому:

SELECT (*) Categories, Parts

Запит поверне таблицю з 5 * 5 \u003d 25 рядків, фрагмент якої наведено нижче:

Cat_IDCat_namePricePart_IDPartCat
10 будматеріали105,00 1 квартири505
10 будматеріали105,00 2 автомашини205
10 будматеріали105,00 3 дошки10
10 будматеріали105,00 4 Шафи30
10 будматеріали105,00 5 книги160
... ... ... ... ... ...
45 техніка65,00 1 квартири505
45 техніка65,00 2 автомашини205
45 техніка65,00 3 дошки10
45 техніка65,00 4 Шафи30
45 техніка65,00 5 книги160

Як видно з прикладу, якщо результат такого запиту і має будь-яку цінність, то це, можливо, наочна цінність в деяких випадках, коли не потрібно вивести структуровану інформацію, тим більше, навіть найпростішу аналітичну вибірку. До речі, можна вказати виведені стовпці з кожної таблиці, але і тоді інформаційна цінність такого запиту не підвищиться.

Але для CROSS JOIN можна задати умову з'єднання! Результат буде зовсім іншим. При використанні оператора "кома" замість явного вказівки CROSS JOIN умова з'єднання задається не словом ON, а словом WHERE.

Приклад 10. Та ж база даних порталу оголошень, таблиці Categories і Parts. Використовуючи перехресне з'єднання, з'єднати таблиці так, щоб дані повністю перетиналися за умовою. Умова - збіг ідентифікатора категорії в таблиці Categories і посилання на категорію в таблиці Parts.

Запит буде наступним:

Запит поверне те ж саме, що і запит в прикладі 1:

PartCatPrice
квартири505 210,00
автомашини205 160,00
дошки10 105,00
Шафи30 77,00

І це збіг не випадковий. Запит c перехресним з'єднанням за умовою сполуки повністю аналогічний запитом з внутрішнім з'єднанням - INNER JOIN - або, враховуючи, що слово INNER - не обов'язкова, просто JOIN.

Таким чином, який варіант запиту використовувати - питання стилю або навіть звички фахівця по роботі з базою даних. Можливо, злиття у формі перехресного з'єднання з умовою для двох таблиць може представлятися більш компактним. Але перевага перехресного з'єднання для більш ніж двох таблиць (це також можливо) дуже суперечливе. В цьому випадку WHERE-умови перетину перераховуються через слово AND. Така конструкція може бути громіздкою і важкою для читання, якщо в кінці запиту є також секція WHERE з умовами вибірки.

Реляційні бази даних і мова SQL

SQL - Урок 6. Об'єднання таблиць (внутрішнє об'єднання)

Припустимо, ми хочемо дізнатися, які теми, і якими авторами були створені. Для цього найпростіше звернутися до таблиці Теми (topics):

Але, що якщо нам необхідно, щоб у відповіді на запит були ідентифікатори авторів, а їх імена? Вкладені запити нам не допоможуть, тому що в кінцевому підсумку вони видають дані з однієї таблиці. А нам треба отримати дані з двох таблиць (Теми і Користувачі) і об'єднати їх в одну. Запити, які дозволяють це зробити, в SQL називаються об'єднаннями.

Синтаксис самого простого об'єднання наступний:

SELECT імена_столбцов_табліци_1, імена_столбцов_табліци_2 FROM імя_табліци_1, імя_табліци_2;

Давайте створимо просте об'єднання:

Вийшло не зовсім те, що ми очікували. Таке об'єднання науково називається декартовим твором, коли кожному рядку першої таблиці ставиться у відповідність кожен рядок другої таблиці. Можливо, бувають випадки, коли таке об'єднання корисно, але це явно не наш випадок.

Щоб результуюча таблиця виглядала так, як ми хотіли, необхідно вказати умову об'єднання. Ми пов'язуємо наші таблиці за ідентифікатором автора, це і буде нашою умовою. Тобто ми вкажемо в запиті, що необхідно виводити тільки ті рядки, в яких значення поля id_author таблиці topics збігаються зі значеннями поля id_user таблиці users:

На схемі буде зрозуміліше:

Тобто ми в запиті зробили таку умову: якщо в обох таблицях є однакові ідентифікатори, то рядки з цим ідентифікатором необхідно об'єднати в одну результуючу рядок.

Зверніть увагу на дві речі:

  • Якщо в одній з поєднуваних таблиць є рядок з ідентифікатором, якого немає в інший об'єднаній таблиці, то в результуючій таблиці рядки з таким ідентифікатором не буде. У нашому прикладі є користувач Oleg (id \u003d 5), але він не створював теми, тому в результаті запиту його немає.
  • При вказівці умови назву стовпця пишеться після назви таблиці, в якій цей стовпець знаходиться (через точку). Це зроблено, щоб уникнути плутанини, адже стовпці в різних таблицях можуть мати однакові назви, і MySQL може не зрозуміти, про які конкретно шпальтах йдеться.
Взагалі, коректний синтаксис об'єднання з умовою виглядає так:

SELECT імя_табліци_1.імя_столбца1_табліци_1, імя_табліци_1.імя_столбца2_табліци_1, імя_табліци_2.імя_столбца1_табліци_2, імя_табліци_2.імя_столбца2_табліци_2 FROM імя_табліци_1, імя_табліци_2 WHERE імя_табліци_1.імя_столбца_по_которому_об'едіняем \u003d імя_табліци_2.імя_столбца_по_которому_об'едіняем;

Якщо ім'я стовпця унікально, то назва таблиці можна опустити (як ми робили в прикладі), але робити це не рекомендується.

Як ви розумієте, об'єднання дають можливість вибирати будь-яку інформацію з будь-яких таблиць, причому об'єднуються таблиць може бути і три, і чотири, та й умова для об'єднання може бути не одне.

Для прикладу давайте створимо запит, який покаже нам всі повідомлення, до яких тем вони відносяться і авторів цих повідомлень. Звичайно, вся ця інформація зберігається в таблиці Повідомлення (posts):

Але щоб замість ідентифікаторів відображалися імена і назви, нам доведеться зробити об'єднання трьох таблиць:

Тобто ми об'єднали таблиці Повідомлення і Користувачі умовою posts.id_author \u003d users.id_user, а таблиці Повідомлення і Теми - умовою posts.id_topic \u003d topics.id_topic

Об'єднання, які ми сьогодні розглядали, називаються внутрішніми об'єднаннями. Такі об'єднання пов'язують рядки однієї таблиці з рядками іншої таблиці (а може ще й третій таблиці). Але бувають ситуації, коли необхідно, щоб в результат були включені рядки, які не мають пов'язаних. Наприклад, коли ми створювали запит, які теми і якими авторами були створені, користувач Oleg в результуючу таблицю не потрапив, тому що тим не створював, а тому і пов'язаної рядки в об'єднаній таблиці не мав.

Тому, якщо нам буде потрібно скласти дещо інший запит - вивести всіх користувачів і теми, які вони створювали, якщо такі є - то нам доведеться скористатися зовнішнім об'єднанням, Що дозволяє виводити всі рядки однієї таблиці і наявні пов'язані з ними рядки з іншої таблиці. Про таких об'єднаннях ми і будемо говорити в наступному уроці.

SQL - Урок 7. Об'єднання таблиць (зовнішнє об'єднання)

Отже, в продовження минулого уроку, нам треба вивести всіх користувачів і теми, які вони створювали, якщо такі є. Якщо ми скористаємося внутрішнім об'єднанням, розглянутим на минулому уроці, то отримаємо в підсумку наступне:

Тобто в результуючій таблиці є тільки ті користувачі, які створювали теми. А нам треба, щоб виводилися всі імена. Для цього ми трохи змінимо запит:

SELECT users.name, topics.topic_name FROM users LEFT OUTER JOIN topics ON users.id_user \u003d topics.id_author;

І отримаємо бажаний результат - всі користувачі і теми, ними створені. Якщо користувач не створював тему, але у відповідному стовпці стоїть значення NULL.

Отже, ми додали в наш запит ключове слово - LEFT OUTER JOIN, Вказавши тим самим, що з таблиці зліва треба взяти все рядки, і поміняли ключове слово WHERE на ON. Крім ключового слова LEFT OUTER JOIN може бути використано ключове слово RIGHT OUTER JOIN. Тоді будуть вибиратися всі рядки з правої таблиці і наявні пов'язані з ними з лівої таблиці. І нарешті, можливо повне зовнішнє об'єднання, яке отримає всі рядки з обох таблиць і зв'яже між собою ті, які можуть бути пов'язані. Ключове слово для повного зовнішнього об'єднання - FULL OUTER JOIN.

Давайте змінимо в нашому запиті лівосторонній об'єднання на правосторонній:

Як бачите, тепер у нас є всі теми (всі рядки з правої таблиці), а ось користувачі тільки ті, які теми створювали (тобто з лівої таблиці вибираються тільки ті рядки, які пов'язані з правого таблицею).

На жаль повне об'єднання СУБД MySQL не підтримує.

Підіб'ємо підсумок цього короткого уроку. Синтаксис для зовнішнього об'єднання наступний.



Сподобалася стаття? поділіться їй