Лого на 91. НЕГ „Проф. Константин Гълъбов“

Модул 3 · Урок 24

Влагане на заявки

Вътрешна заявка на мястото на елемент от външната: влагане в WHERE (сравнение, IN, ANY, ALL) и влагане във FROM — с правилата, които трябва да спазваме.

Основание и пример

Понякога нужните кортежи не могат да се получат с една заявка. Пример: таблица Успех (Име, Фамилия, Average). Търсим учениците с личен среден успех по-висок от средния за класа. Не можем да напишем директен SELECT — средният успех на класа не ни е известен предварително. Двете стъпки:

  • Стъпка 1: SELECT Avg(Average) FROM Успех; — една стойност X (средният успех на класа).
  • Стъпка 2: SELECT * FROM Успех WHERE Average > X;

SQL позволява да заменим X направо с кода на първата заявка, затворена в кръгли скоби:

Ключово

SELECT * FROM Успех WHERE Average > (SELECT Avg(Average) FROM Успех);

Механизмът е подобен на извикване на функция в израз: пресмята се стойността и замества извикването.

Внимание

Същото влагане работи и в DELETE: DELETE FROM Успех WHERE Average < (SELECT Avg(Average) FROM Успех); — изтрива слабите ученици. Не правете този експеримент с таблица, която ви е нужна!

Правилата на влагането

Влагане на заявки

Поставянето на една заявка на мястото на елемент на друга. Външна е заявката, в която влагаме; вътрешна — вложената (най-често SELECT).

  • Вътрешната заявка е винаги в кръгли скоби.
  • В клаузата WHERE на външната може да се използва резултат само с една колона; в клаузата FROM — таблица с няколко колони.
  • Ако вътрешната връща колона с повече от един ред — в WHERE ползваме операциите за сравняване с множество: IN, NOT IN, ANY, ALL. Иначе — само сравнение стойност със стойност.
  • Вътрешната заявка не може да бъде сортирана.

За ефективността

Влагане във влагане е допустимо, но конструкцията е сложна и не се препоръчва. Заявките с влагане не са много ефективни при големи таблици — избягвайте ги, ако могат да се заменят с умна употреба на JOIN.

Влагане в клаузата WHERE

IN / NOT IN

Бележка

SELECT Ученик.Фамилия FROM Ученик WHERE Ученик.Клас IN (SELECT Клас FROM Учител WHERE [Фамилия на учител] = 'Иванов');

— фамилиите на всички ученици, на които преподава учителят Иванов. С NOT IN — на които НЕ преподава.

ANY и ALL

  • атрибут > ANY (вътрешна) — кортежите, в които стойността е по-голяма от някоя от извлечените.
  • атрибут > ALL (вътрешна) — по-голяма от всички извлечени стойности.

Влагане в клаузата FROM

На мястото на таблицата във FROM може да застане цяла заявка — например резултатът от тройното INNER JOIN от предишния урок.

Най-важното правило

Когато влагаме SELECT във FROM и после извличаме стойности от атрибути на временната таблица — задаваме на тези атрибути наши имена с AS. Иначе SQL им поставя служебни имена, които не знаем и не можем да използваме във външната заявка.

Помисли (въпроси от учебника)

Имат ли смисъл заявките: SELECT * FROM (SELECT * FROM Успех WHERE Average >= 4.00) WHERE Average < 5.50; и SELECT * FROM (SELECT Име AS ИИме, Фамилия AS ФФамилия FROM Успех) WHERE Average >= 4.00; Първата се заменя с една заявка (AND); втората е грешна — Average не съществува във временната таблица!

Какво трябва да запомниш

  • Влагане = заявка на мястото на елемент; вътрешната е винаги в кръгли скоби.
  • В WHERE: една колона; един ред → сравнение, много редове → IN/NOT IN/ANY/ALL.
  • Вътрешната заявка не се сортира.
  • Във FROM: задължително AS имена на атрибутите, ползвани отвън.
  • При големи таблици — предпочитай JOIN пред влагане.