Вложени заявки в SQL
Езикът SQL ви позволява да влагате една заявка в друга заявка. Това прави възможно да се напише една много голяма заявка, която ще направи нещо голямо и сложно, въпреки че четимостта на codeа е значително намалена.
В зависимост от това колко стойности се връщат от подзаявките, областта, където могат да бъдат приложени, се променя. Има общо три опции:
- Подзаявката връща една единствена стойност (една колона и един ред).
- Подзаявката връща списък със стойности (table с една колона).
- Подзаявката връща table (много колони, произволен брой редове).
Нека разгледаме по един пример за всеки случай.
Подзаявка със скаларен резултат
Нека намерим списък на всички наши служители от tableта на служителите, чиято заплата е по-висока от средната за компанията. Как можем да го направим?
Можем лесно да филтрираме служителите, като сравняваме тяхната заплата със средната, ако я знаем предварително. В същото време вече сме написали заявка, която ни позволява да изчислим средната заплата на служителите на компанията. Да си го припомним:
SELECT AVG(salary) FROM employee
Тогава MySQL ни върна стойността: 76833.3333 .
Как сега да намерите списък на всички служители, чиято заплата е над средната? Освен това е много просто:
SELECT * FROM employee
WHERE salary > 76833.3333
Резултатът от тази заявка ще бъде:
document за самоличност | име | професия | заплата |
---|---|---|---|
1 | Ivanов Ivan | Програмист | 100 000 |
2 | Peterов Петър | Програмист | 80 000 |
4 | Рабинович Мойша | Директор | 200 000 |
И сега просто комбинираме двете заявки, като заместваме първата заявка instead of стойността 76833:
SELECT * FROM employee
WHERE salary > (SELECT AVG(salary) FROM employee)
Резултатът от тази заявка ще бъде същият:
document за самоличност | име | професия | заплата |
---|---|---|---|
1 | Ivanов Ivan | Програмист | 100 000 |
2 | Peterов Петър | Програмист | 80 000 |
4 | Рабинович Мойша | Директор | 200 000 |
Подзаявка със списък от стойности
Спомняте ли си едно време имахме задача - да намерим всички записи от една table, за които няма съответстващи записи от друга?
Имаше и тази снимка:
![](https://cdn.codegym.cc/images/article/a0eff64c-0bb4-4480-833e-c1305cd03a5e/512.jpeg)
Ако не се лъжа, задачата е следната: показване на списък с всички служители от tableта на служителите, за които няма задачи в tableта със задачи .
Нека също намерим решение в две стъпки.
Първо, нека напишем заявка, която ще върне идентификатора на всички служители, които имат задачи в tableта със задачи. Само запомнете две неща:
- премахнете дубликати - използвайте ключовата дума DISTINCT.
- премахнете NULL стойности от резултата.
SELECT DISTINCT employee_id FROM task
WHERE employee_id IS NOT NULL
И тук получихме красив резултат от такава заявка:
ИД на служител |
---|
1 |
2 |
5 |
4 |
6 |
Нека временно го запишем за удобство като последователност: 1,2,5,4,6. Сега нека напишем втора заявка - към tableта на служителите, която ще върне списък със служители, чийто идентификатор не се съдържа в първия списък:
SELECT * FROM employee
WHERE id NOT IN (1,2,5,4,6)
И резултатът от тази заявка:
document за самоличност | име | професия | заплата | възраст | дата на присъединяване |
---|---|---|---|---|---|
3 | Ivanов Сергей | Тестер | 40 000 | тридесет | 2014-01-01 |
И сега, Howто в предишния пример, можете да комбинирате и двете заявки, като просто замените тялото на първата заявка instead of списъка с идентификатори.
SELECT * FROM employee
WHERE id NOT IN (
SELECT DISTINCT employee_id FROM task
WHERE employee_id IS NOT NULL
)
GO TO FULL VERSION