Interogări imbricate în SQL
Limbajul SQL vă permite să imbricați o interogare într-o altă interogare. Acest lucru face posibilă scrierea unei interogări foarte mari care va face ceva mare și complex, deși lizibilitatea codului este mult redusă.
În funcție de câte valori sunt returnate de subinterogări, zona în care pot fi aplicate se modifică. Există trei opțiuni în total:
- Subinterogarea returnează o singură valoare (o coloană și un rând).
- Subinterogarea returnează o listă de valori (un tabel cu o coloană).
- Subinterogarea returnează un tabel (mai multe coloane, orice număr de rânduri).
Să ne uităm la un exemplu pentru fiecare caz.
Subinterogare cu rezultat scalar
Să găsim o listă cu toți angajații noștri din tabelul de angajați al căror salariu este mai mare decât media pentru companie. Cum putem face acest lucru?
Putem filtra cu ușurință angajații comparând salariul lor cu media dacă o știm dinainte. Totodată, am scris deja o interogare care ne permite să calculăm salariul mediu al angajaților companiei. Să ne amintim:
SELECT AVG(salary) FROM employee
Apoi MySQL ne-a returnat valoarea: 76833.3333 .
Cum să găsești acum o listă cu toți angajații al căror salariu este peste medie? De asemenea, este foarte simplu:
SELECT * FROM employee
WHERE salary > 76833.3333
Rezultatul acestei interogări va fi:
id | Nume | ocupaţie | salariu |
---|---|---|---|
1 | Ivanov Ivan | Programator | 100000 |
2 | Petrov Petr | Programator | 80000 |
4 | Rabinovici Moisha | Director | 200000 |
Și acum combinăm ambele cereri înlocuind prima cerere în loc de valoarea 76833:
SELECT * FROM employee
WHERE salary > (SELECT AVG(salary) FROM employee)
Rezultatul acestei interogări va fi același:
id | Nume | ocupaţie | salariu |
---|---|---|---|
1 | Ivanov Ivan | Programator | 100000 |
2 | Petrov Petr | Programator | 80000 |
4 | Rabinovici Moisha | Director | 200000 |
Subinterogare cu listă de valori
Îți amintești cândva am avut o sarcină - să găsim toate înregistrările dintr-un tabel pentru care nu există înregistrări corespunzătoare din altul?
Era si aceasta poza:
![](https://cdn.codegym.cc/images/article/a0eff64c-0bb4-4480-833e-c1305cd03a5e/512.jpeg)
Dacă nu mă înșel, sarcina este următoarea: afișați o listă cu toți angajații din tabelul de angajați pentru care nu există sarcini în tabelul de sarcini .
Să găsim și o soluție în doi pași.
Mai întâi, să scriem o interogare care va returna id-ul tuturor angajaților care au sarcini în tabelul de sarcini. Nu uitați decât două lucruri:
- eliminați duplicatele - utilizați cuvântul cheie DISTINCT.
- eliminați valorile NULL din rezultat.
SELECT DISTINCT employee_id FROM task
WHERE employee_id IS NOT NULL
Și aici am obținut un rezultat frumos al unei astfel de solicitări:
card de identitate al angajatului |
---|
1 |
2 |
5 |
4 |
6 |
Să-l notăm temporar pentru comoditate, ca o secvență: 1,2,5,4,6. Acum să scriem o a doua interogare - în tabelul de angajați, care va returna o listă de angajați al căror id nu este conținut în prima listă:
SELECT * FROM employee
WHERE id NOT IN (1,2,5,4,6)
Și rezultatul acestei interogări:
id | Nume | ocupaţie | salariu | vârstă | Data înscrierii |
---|---|---|---|---|---|
3 | Ivanov Serghei | Tester | 40000 | treizeci | 01-01-2014 |
Și acum, ca și în exemplul anterior, puteți combina ambele solicitări pur și simplu înlocuind corpul primei solicitări în locul listei de id-uri.
SELECT * FROM employee
WHERE id NOT IN (
SELECT DISTINCT employee_id FROM task
WHERE employee_id IS NOT NULL
)
GO TO FULL VERSION