Amikor egy lekérdezésben egy másik lekérdezés eredményét szeretnénk felhasználni, jól jön az SQL nyelvek egyik tulajdonsága, a lekérdezések egymásba ágyazásának lehetősége.
Ez bizonyos értelemben hasonló ahhoz, mint programozáskor egymásba ágyazott ciklusokat használunk, de mint minden hasonlat ez is sántít. A lényeg az, hogy az al-lekérdezést mindig előbb hajtja végre a szerver, mint a fő lekérdezést!
Az elméleti megfontolás helyett nézzünk példákat
1. Az iskolai átlagnál jobb átlagú diákok
Ha meg szeretnénk tudni, hogy melyek azok a diákok, akik az iskolai átlagnál jobbak, akkor először az iskolai átlagot kell kiszámolni, majd szűrni azokat, akiknek az átlaga jobb!
Az al-lekérdezés egy értéket ad vissza, az iskola összes osztályzatának átlagát. A fő lekérdezés ehhez az átlaghoz képest jeleníti meg csak azokat, akik ennél az átlagnál jobbak.
SELECT DID, AVG(osztalyzat) AS Atlag FROM Diakok
GROUP BY DID
HAVING Atlag > (SELECT AVG(osztalyzat) AS atlageredmeny FROM Osztalyzatok)
2. Hogyan tudjuk az átlagos létszámnál kisebb létszámú osztályzatokat megkeresni?
Nézzük meg a kiértékelés sorrendje szerinti lekérdezéseket, majd a végén az egész lekérdezést!
A legbelső lekérdezésekkel kezdődik a kiértékelés, azaz kiszámoljuk a tanulók összes létszámát
1.) SELECT DISTINCT Osztaly AS a FROM Diakok
Listát készítünk a különböző osztályokról!
SELECT COUNT( Diakok.DID ) AS sum FROM Diakok
Kiszámoljuk az osztályok számát?
2.) SELECT COUNT(D.a) As db FROM (SELECT DISTINCT Osztaly AS a FROM Diakok) D
Ebben a lekérdezésben a "D" a lekérdezés ALIASA. MYSQL-ben egy lekérdezéshez létrehozhatunk alias nevet, amelyet aztán a lekérdezés többi pontján használhatunk.
Az 1.) és 2.) lekérdezés egy-egy értéket ad eredményül és ezeket elosztjuk egymással. Ezt az SQL-ben úgy tudjuk megoldani, hogy a SELECT után végrehajtjuk a kifejezést és ALIAS nevet adunk neki
SELECT
( SELECT COUNT( diakok.DID ) AS sum FROM diakok ) /
( SELECT COUNT(D.a) AS db FROM (SELECT DISTINCT Osztaly AS a FROM Diakok) D )
AS Atlag
Végül az így megkapott átlag értéknél a kisebb létszámú osztályok neveit listázzuk ki:
SELECt `Osztaly`, Count(*) AS Fo FROM `diakok`
GROUP BY osztaly
HAVING
Fo < (
SELECT
( SELECT COUNT( diakok.DID ) AS sum FROM diakok ) /
( SELECT COUNT(D.a) FROM (SELECT DISTINCT Osztaly AS a FROM Diakok) D )
AS Atlag
)
Ha bárki azt gondolja, hogy ez könnyű, hát nem az, de működik!
További egyszerűbb példák
Kíváncsiak vagyunk Kiss János osztalytársainak a nevére:
SELECT Nev FROM Diakok WHERE Osztaly =
(SELECT Osztaly FROM Diakok WHERE Nev = 'Kiss János');
Megjegyzés
Ha egy al-lekérdezés eredményét egy összehasonlításban (WHERE, HAVING) szeretnénk használni, akkor az al-lekérdezés csak egy értéket adhat vissza eredményül.
Al-lekérdezések esetén gyakran használjuk ugyanazt a táblanevet, mint a fő lekérdezésekben. Ilyenkor a lekérdezésben kötelező ALIAS nevet használni, mert az SQL ennek alapján tudja eldönteni, hogy melyik lekérdezés mezőjét használjuk!