Довідковий матеріал з основних мов програмування і верстки сайтів.
Готова методика створення простих і складних динамічних сайтів, з використанням PHP і MySQL.
Розробка веб-сайтів під "ключ".
Розробка окремих фрагментів сайтів, консультації з питань верстки веб-сторінок і веб-програмування.
Веб-інструмент
Веб-майстерня
Веб-послуги
Веб-графіка
Веб-ресурси
Хочете бути в курсі подій, що відбуваються на сайті? Підпишіться на отримання останніх новин та статей.
Подивіться в Google
Витяг даних з декількох таблиць
Ці дані зберігаються в різних таблицях, оскільки відносяться до різних реальних об'єктів. Це один з принципів доброго проекту бази даних.
Хоча на перший погляд операція з'єднання досить проста, насправді це один з найбільш складних і тонких аспектів SQL. В MySQL реалізовано кілька різних типів з'єднання, кожен з яких призначений для певних цілей.
Просте з'єднання двох таблиць
Почнемо з пошуку Сидорова Володимира:
mysql> select orders.orderid, orders.amount, orders.date
-> From customers, orders
-> Where customers.name = 'Сидоров Володимир'
-> And customers. customerid = orders.customerid;
Результат буде таким:
Тут варто було б відзначити кілька моментів.
Перераховуючи дві таблиці, ви також вказуєте тип з'єднання, можливо, навіть не знаючи його. Кома між назвами таблиць еквівалентна конструкціям INNER JOIN (внутрішнє з'єднання) або CROSS JOIN (перехресне з'єднання). Такий тип з'єднання ще називають повним з'єднанням або декартових твором таблиць. Це означає наступне: "Взяти зазначені таблиці і зробити з них одну велику. Велика таблиця повинна містити рядок для будь-якої можливої комбінації рядків з кожної зазначеної в списку таблиці, незалежно від того мають вони сенс чи ні". Іншими словами, ми отримуємо таблицю, в якій кожен рядок таблиці customer сопостовляется кожному рядку таблиці orders незалежно від того, які замовлення були зроблені конкретними клієнтами.
У більшості випадків таке з'єднання не має великого сенсу. Як правило, нам потрібні рядки, які дійсно збігаються, тобто коли конкретні замовлення відповідають клієнтам, якими вони були зроблені.
Це досягається шляхом приміщення в конструкцію WHERE умови з'єднання. Це особливий тип умовного оператора, який пояснює, які атрибути відбивають відносини між двома таблицями. В даному випадку наша умова з'єднання було таким:
and customers. customerid = orders.customerid
що наказує MySQL поміщати в результуючу таблицю тільки ті рядки, для яких customerid з таблиці customer збігається з customerid з таблиці orders.
Внісши ця умова в запит, ми, по суті, отримали з'єднання іншого типу -З'єднання по рівності.
Зверніть увагу на точкову нотацію, якої ми скористалися для уточнення конкретного стовпця конкретної таблиці. Так, customers.customerid відноситься до колонку customerid з таблиці Customers, a orders.customerid - до колонку customerid з таблиці оrders.
Точкова нотація необхідна, коли імена стовпців неоднозначні, що трапляється, якщо одні й ті ж імена зустрічається в декількох таблицях.
Як розширення його можна використовувати для розрізнення імен стовпців з різних баз даних. У нашому прикладі позначення виглядає як table.column (табліца.столбец). Можна вказати і інакше - database.table.column (база_данних.табліца.столбец), наприклад, для перевірки умови на зразок:
З іншого боку, точкову нотацію можна застосовувати і для всіх посилань на стовпці в запиті. Це часто позбавляє від зайвого головного болю, особливо коли запити стають все більш складними. MySQL цього не вимагає, але зручний читабельні запити - це не так вже й погано. Якщо ви помітили, ми дотримуємося цього принципу у всіх наших прикладах, взяти хоча б ось таку умову:
customers. name = 'Сидоров Володимир'
Стовпець name присутній тільки в таблиці customers, тому його необов'язковий але вказувати, але так, в общем-то, зрозуміліше.
Ці три і більше таблиць
З'єднання великої кількості таблиць не складніше з'єднання двох таблиць. Головне правило таке - таблиці потрібно об'єднувати попарно, з огляду на умови об'єднання. Це можна представити у вигляді відносин між таблицями в кожній такій парі.
Наприклад, якщо потрібно дізнатися, хто з клієнтів замовив книги по Розробці веб-сайту за допомогою РНР і Mysql, необхідно відстежити ці відносини в рамках невеликої кількості таблиць.
Необхідно буде знайти клієнтів, які розмістили, по крайней мере, один замовлення, який містить order_items відповідний книзі по Розробці веб-сайту за допомогою РНР і Mysql. З таблиці сustomers перебираємося в таблицю оrders, використовуючи customerid, як і в попередніх випадках. З таблиці оrders в таблицю оrder_items, використовуючи orderid. З order_items - в таблицю books за потрібною книгою, керуючись номером ISBN. Після того як всі зв'язки встановлені, можемо запросити книги зі словом "Розробка" в назві і отримати в результаті імена клієнтів, які купили будь-яку з цих книг.
Давайте подивимося на запит, виконує описані дії:
mysql> select customers.name
-> From customers, orders, order_items, books
-> Where customers.customerid = orders.customerid
-> And orders.orderid = order_items.orderid
-> And order_items.isbn = books.isbn
-> And books.title like '% Розробка%';
Цей запит поверне наступний результат:
Зверніть увагу, що були відслідковані дані з чотирьох різних таблиць, а щоб зробити це за допомогою об'єднання з рівності, знадобилися три різних умови об'єднання. Зазвичай кожній парі таблиць потрібно одна умова об'єднання, таким чином, кількість умов об'єднання на одиницю менше кількості об'єднуються таблиць. Це правило великого пальця може стати в нагоді при налагодженні запитів, які працюють нестабільно. Перевірте свої умови об'єднання і переконайтеся в тому, що ви весь час слідували наміченим шляхом, від того, що ви вже знаєте - до того, що потрібно дізнатися.
Пошук незбіжних рядків
Інший поширений в Mysql тип з'єднання - лівосторонній з'єднання.
У попередніх прикладах відбиралися тільки ті рядки, в яких спостерігалося відповідність між таблицями. Однак можуть знадобитися і рядки, в яких відповідність відсутня. Наприклад, потрібно знайти клієнтів, які не зробили жодного замовлення, або книги, які взагалі ніхто не замовив.
Найпростіший варіант відповіді на таке питання в Mysql припускає використання лівостороннього з'єднання, при якому виконується пошук рядків за вказаною умові з'єднання двох таблиць. Якщо в зазначеній справа таблиці немає підходящої рядки, до результато додається рядок з нульовими значеннями у шпальтах.
mysql> select customers. customerid, customers.name, orders. orderid
-> From customers left join orders
-> On customers.customerid = orders. customerid;
Даний запит SQL використовує лівосторонній з'єднання для таблиць customers і orders. Його синтаксис щодо умов з'єднання дещо іншою. Умова з'єднання вказується в спеціальній конструкції ON.
Ось так виглядає результат запиту:
З результату видно, що для Алексєєва Івана немає відповідного ідентифікатора закза, оскільки його поле orderid має значення NULL.
Якщо необхідно знайти тільки тих клієнтів, які нічого не замовляли, цього можна досягти, виконавши перевірку на значення NULL в полі первинного ключа правої таблиці (в даному випадку orderid)? так як рядки з реальними значеннями не можуть містити значення NULL:
mysql> select customers. customerid, customers. name
-> From customers left join orders
-> Using (customerid)
-> Where orders. orderid is NULL;
Результат запиту виглядає наступним чином:
Ймовірно, ви звернули увагу на те, що в цьому прикладі ми використовували дещо інший синтаксис умови з'єднання. Лівосторонній з'єднання підтримує синтаксис ON, який був використаний в першому прикладі, так і синтаксис USING, який застосовувався у другому. Синтаксис USING не припускав вказівки таблиці, з якої надходить атрибут з'єднання, тому, щоб його можна було використовувати, стовпці в обох таблицях повинні називатися однаково.
Використання інших імен таблиць: псевдоніми
Часто буває дуже зручно, а часом і необхідно звертатися до таблиць під іншими іменами. Такі імена називаються псевдонімами (aliase). Їх можна створити в самому початку запиту, а потім користуватися в міру необхідності. Псевдоніми дуже зручні, все одно, що ярлик на робочому столі. Погляньте, як виглядає досить об'ємний запит, розглянутий нами раніше, переписаний з використанням псевдонімів:
mysql> select c.name
-> From customers as c, orders as o, order_items as oi, books as b
-> Where c.customerid = o.customerid
-> And o.orderid = oi.orderid
-> And oi. isbn = b.isbn
-> And b.title like '% Розробка%';
Для присвоєння псевдоніма в таблиці використовується конструкція AS. Крім того, псевдоніми можна давати стовпцями, проте до цього ми повернемося після того, як розглянемо узагальнені функції.
Табличні псевдоніми необхідні в разі об'єднання таблиці з самою собою. Це звучить набагато більш загрозливо і містично, ніж є насправді. А такий підхід дуже зручний для пошуку рядків в тій же таблиці, в якій є і інші потрібні нам значення. Якщо потрібно знайти клієнтів, які живуть в одному місті, скажімо, з метою створення читацького клубу, можна присвоїти одній і тій же таблиці (сustomers) два різні псевдоніми:
mysql> select c1.name, c2. name, c1. city
-> From customers as c1, customers as c2
-> Where c1. city = c2. city
-> And c1.name! = C2.name;
Ми робимо вигляд, що таблиця customers це дві різні таблиці з1 і с2, і виконуємо їх з'єднання по стовпцю city. Друга умова, c1.name! = C2.name, необхідно для запобігання зіставлення клієнта самому собі.
Резюме за типами з'єднань
У таблиці перераховані різні розглянуті раніше типи з'єднань. Існують також кілька інших типів, однак наведені в таблиці з'єднання використовуються найбільш часто.