Beágyazott lekérdezések SQL-ben

Az SQL nyelv lehetővé teszi, hogy egy lekérdezést egy másik lekérdezésbe ágyazzon be. Ez lehetővé teszi egy nagyon nagy lekérdezés írását, amely valami nagy és összetett feladatot végez, bár a kód olvashatósága jelentősen csökken.

Attól függően, hogy hány értéket adnak vissza az allekérdezések, változik az a terület, ahol alkalmazhatók. Összesen három lehetőség van:

  • Az allekérdezés egyetlen értéket ad vissza (egy oszlopot és egy sort).
  • Az allekérdezés értéklistát ad vissza (egy oszlopos táblázat).
  • Az allekérdezés egy táblázatot ad vissza (sok oszlop, tetszőleges számú sor).

Nézzünk egy-egy példát minden esetre.

Allekérdezés skaláris eredménnyel

Keressük meg a munkavállalói táblázatból azon munkavállalóink ​​listáját, akiknek a fizetése magasabb a vállalati átlagnál. Hogyan tehetjük meg?

Könnyedén szűrhetjük a dolgozókat, ha előre tudjuk, összehasonlítjuk fizetésüket az átlaggal. Ugyanakkor már írtunk egy lekérdezést, amivel kiszámolhatjuk a cég dolgozóinak átlagkeresetét. Emlékezzünk rá:

SELECT AVG(salary) FROM employee 

Ezután a MySQL visszaadta nekünk a következő értéket: 76833.3333 .

Hogyan találhat most egy listát az összes alkalmazottról, akinek a fizetése meghaladja az átlagot? Ez is nagyon egyszerű:

 SELECT * FROM employee 
   WHERE salary > 76833.3333 

A lekérdezés eredménye a következő lesz:

id név Foglalkozása fizetés
1 Ivanov Iván Programozó 100 000
2 Petrov Petr Programozó 80000
4 Rabinovics Moisa Rendező 200 000

És most csak kombináljuk mindkét kérést úgy, hogy a 76833 érték helyett az első kérést helyettesítjük:

   SELECT * FROM employee 
   WHERE salary > (SELECT AVG(salary) FROM employee) 

A lekérdezés eredménye ugyanaz lesz:

id név Foglalkozása fizetés
1 Ivanov Iván Programozó 100 000
2 Petrov Petr Programozó 80000
4 Rabinovics Moisa Rendező 200 000

Allekérdezés értéklistával

Emlékszel, valamikor régen volt egy feladatunk - megkeresni az egyik táblából az összes olyan rekordot, amelyhez nincs megfelelő rekord egy másik táblából?

Ez a kép is volt:

Ha nem tévedek, a feladat a következő: jelenítse meg az összes alkalmazott listáját az alkalmazotti táblából, amelyhez nincs feladat a feladattáblázatban .

Találjunk megoldást is két lépésben.

Először írjunk egy lekérdezést, amely visszaadja az összes olyan alkalmazott azonosítóját, akinek a feladattáblájában van feladatok. Csak emlékezz két dologra:

  • duplikátumok eltávolítása – használja a DISTINCT kulcsszót.
  • távolítsa el a NULL értékeket az eredményből.
SELECT DISTINCT employee_id FROM task 
   WHERE employee_id IS NOT NULL

És egy ilyen kérés gyönyörű eredményét kaptuk:

munkavállalói azonosító
1
2
5
4
6

Ideiglenesen írjuk le a kényelem kedvéért sorozatként: 1,2,5,4,6. Most írjunk egy második lekérdezést - az alkalmazotti táblába, amely visszaadja azon alkalmazottak listáját, akiknek az azonosítója nem szerepel az első listában:

SELECT * FROM employee  
WHERE id NOT IN (1,2,5,4,6)

És ennek a lekérdezésnek az eredménye:

id név Foglalkozása fizetés kor csatlakozás dátuma
3 Ivanov Szergej Vizsgáló 40000 harminc 2014-01-01

És most, az előző példához hasonlóan, mindkét kérést kombinálhatja úgy, hogy az azonosítólista helyett egyszerűen helyettesíti az első kérelem törzsét.

 SELECT * FROM employee 
   WHERE id NOT IN ( 
      	SELECT DISTINCT employee_id FROM task 
      	WHERE employee_id IS NOT NULL 
   )