В. М. Дубовой Укладач д т. н., проф

Вид материалаДокументы

Содержание


Особливості багатотабличних запитів
Select teachers.tfam, predmet.pname from teachers, predmet
Використання вкладених запитів
Select * from usp where snum = (select snum from students
Select * from predmet where tnum =
Select * from predmet where (select distinct tnum from teachers
Подобный материал:
1   2   3   4   5   6   7

Особливості багатотабличних запитів



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

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

Припустимо необхідно поставити у відповідність викладачу навчальні предмети, що він веде. Фактично SQL прийдеться вибирати з таблиці викладачів відповідний йому код і, переглядаючи таблицю предметів, здійснювати пошук відповідного коду. Це можна реалізувати наступним запитом:

SELECT TEACHERS.TFAM, PREDMET.PNAME FROM TEACHERS, PREDMET

WHERE TEACHERS.TNUM = PREDMET.TNUM;


Висновок цього запиту представлений нижче:

TFAM

PNAME

Викулина

Фізика

Костыркин

Хімія

Казанко

Математика

Позднякова

Економіка

Загарийчук

Філософія



Використання вкладених запитів



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

SELECT * FROM USP WHERE SNUM = (SELECT SNUM FROM STUDENTS

WHERE SFAM = 'Поляків')

Результат цього запиту буде наступний:


UNUM

OCENKA

UDATE

SNUM

PNUM

1001

5

10/06/1999

3412

2001

1004

4

12/06/1999

3412

2003

Щоб виконати основний запит, SQL спочатку повинний оцінити внутрішній запит (його називають подзапросом) усередині пропозиції WHERE. Відбувається це традиційним образом, тобто виповнюється вкладений запит, що витягає необхідні для визначення значення предиката дані, а тільки потім - основний. Зрозуміло, подзапрос повинний вибрати тільки одне поле, а тип даних цього полючи повинний збігатися з тим значенням, з яким він буде порівнюватися в предикаті.

У деяких випадках варто використовувати DISTINCT для того, щоб у подзапросе одержати одиночне значення. Припустимо, що викладачі можуть вести заняття по різних дисциплінах. Тоді для одержання відповіді на питання про те, які дисципліни веде викладач Никулина, можна скористатися запитом:

SELECT * FROM PREDMET WHERE TNUM =

(SELECT DISTINCT TNUM FROM TEACHERS WHERE TFAM = 'Никулина');

У результаті буде отримано:

PNUM

PNAME

TNUM

HOURS

COURS

2001

Фізика

4001

34

1

Подзапрос установив, що значення полючи TNUM збіглося з прізвищем Викулина при значенні 4001, а потім основний запит виділив Всі записи з цим значенням TNUM з таблиці предметів. Т.к., узагалі говорячи, могло вийти, що викладач веде кілька предметів, то фраза PISTTNCT у даному випадку обов'язкова - якщо подзапрос повернув би більш одного значення, те це викликало би помилку.

Варто мати на увазі, що предикати з подзапросами є необоротними, тобто предикати, що включають подзапросы, використовують конструкцію в наступному порядку:

<ВИРАЖЕННЯ> <ОПЕРАТОР> <ПОДЗАПРОС>,

ні в якому разі не

<ПОДЗАПРОС> <ОПЕРАТОР> <ВИРАЖЕННЯ>,

чи

<ПОДЗАПРОС> <ОПЕРАТОР> <ПОДЗАПРОС>,

інакше кажучи, що предыдет приклад, записаний у такий спосіб:

SELECT * FROM PREDMET WHERE (SELECT DISTINCT TNUM FROM TEACHERS

WHERE TFAM = 'Викулина') * TNUM;

є невірним.