
- •Теоретичні відомості об'єднання таблиць
- •Імена таблиць і стовпців
- •Створення об'єднання
- •Об'єднання таблиць через довідкову цілісність
- •Об'єднання таблиць по рівності значень у стовпцях і інші види об'єднань
- •Об'єднання більше двох таблиць
- •Як працює підзапит?
- •Значення, які підзапит може виводити
- •Distinct з підзапитами
- •Використання агрегатних функцій в підзапитах
- •Використання підзапитів, які видають багато рядків За допомогою оператора in
- •Підзапити вибирають поодинокі стовпці
- •Використання виразів в підзапитах
- •Підзапити в пропозиції having
- •Варіанти завдань :
Об'єднання більше двох таблиць
Ви можете також створювати запити, що об'єднують більше двох таблиць. Припустимо, що ми хочемо знайти усі замовлення замовників, що не знаходяться в тих містах, де знаходяться їх продавці. Для цього необхідно зв'язати усе три наші типові таблиці (висновок показаний на Малюнку 8.4) :
SELECT onum, cname, Orders.cnum, Orders.snum
FROM Salespeople, Customers, Orders
WHERE Customers.city < > Salespeople.city
AND Orders.cnum = Customers.cnum
AND Orders.snum = Salespeople.snum;
=============== SQL Execution Log ==============
| |
| SELECT onum, cname, Orders.cnum, Orders.snum |
| FROM Salespeople, Customers, Orders |
| WHERE Customers.city < > Salespeople.city |
| AND Orders.cnum = Customers.cnum |
| AND Orders.snum = Salespeople.snum; |
| =============================================== |
| onum cname cnum snum |
| ------ ------- ----- ----- |
| 3001 Cisneros 2008 1007 |
| 3002 Pereira 2007 1004 |
| 3006 Cisneros 2008 1007 |
| 3009 Giovanni 2002 1003 |
| 3007 Grass 2004 1002 |
| 3010 Grass 2004 1002 |
===============================================
Малюнок 8.4 Об'єднання трьох таблиць
Хоча ця команда виглядає швидше як комплексна, ви можете йти за логікою, просто перевіряючи, що замовники не розміщені в тих містах, де розміщені їх продавці (збіг двох snum полів), і що перераховані замовлення виконані за допомогою цих замовників (збіг замовлень з полями cnum і snum в таблиці Замовлень).
Як працює підзапит?
За допомогою SQL ви можете вкладати запити друга в друга. Зазвичай внутрішній запит генерує значення, яке перевіряється в предикаті зовнішнього запиту, визначального, вірне воно або ні. Наприклад, припустимо, що ми знаємо ім'я продавця : Motika, але не знаємо значення його поля snum і хочемо витягнути усі замовлення з таблиці Замовлень. Ось спосіб зробити це (висновок показаний на Мал. 10.1 ) :
SELECT *
FROM Orders
WHERE snum =
(SELECT snum
FROM Salespeople
WHERE sname = 'Motika');
Щоб оцінити зовнішній (основний) запит, SQL спочатку повинен оцінити внутрішній запит (чи підзапит) усередині пропозиції WHERE. Він робить це так, як і повинен робити запит, що має єдину мету, - відшукати через таблицю Продавців усі рядки, де поле sname дорівнює значенню Motika, а потім витягнути значення поля snum цих рядків.
Єдиним знайденим рядком, природно, буде snum = 1004. Проте SQL не просто видає це значення, а поміщає його в предикат основного запиту замість самого підзапиту, так щоб предикат прочитав, що
WHERE snum = 1004
=============== SQL Execution Log ==============
| |
| SELECT * |
| FROM Orders |
| WHERE snum = |
| (SELECT snum |
| FROM Salespeople |
| WHERE sname = 'Motika'); |
|=================================================|
| onum amt odate cnum snum |
| ----- ------- ---------- ----- ----- |
| 3002 1900.10 10/03/1990 2007 1004 |
| |
=================================================
Малюнок 10.1 Використання підзапиту
Основний запит потім виконується як завжди з вищезгаданими результатами. Зрозуміло, підзапит повинен вибрати один, і тільки один, стовпець, а тип даних цього стовпця повинен співпадати з тим значенням, з яким він порівнюватиметься в предикаті.
Часто, як показано вище, вибране поле і його значення матимуть однакові імена (в даному випадку snum), але це не обов'язково. Звичайно, якби ми вже знали номер продавця Motika, ми могли б просто надрукувати WHERE snum = 1004 і працювати далі з підзапитом в цілому, але це було б не так універсально. Цей же запит продовжуватиме працювати, навіть якщо номер Motika змінився, а за допомогою простої зміни імені в підзапиті ви можете використовувати його для чого завгодно.