Belső lekérdezés

Az SQL nyelvben lehetőség van arra, hogy a lekérdezések feltételében is használjunk SQL lekérdező parancsot. Ilyenkor megkülönböztetünk külső és belső SELECT parancsot. Az ilyen lekérdezéseket beágyazott vagy belső lekérdezéseknek nevezzük.

Belső lekérdezést (subquery-t) akkor használunk, amikor egy lekérdezés eredményét egy másik lekérdezésben kell felhasználni. Az adattáblákból valamilyen "globális" információt szeretnénk kinyerni.

A belső SELECT-et mindig zárójelpárba kell megadni.
A belső SELECT is tartalmazhat belső SELECT-et, vagyis a SELECT-ek egymásba ágyazhatók.
Először a belső, majd a külső lekérdezés hajtódik végre.

A belső SELECT-ből is hivatkozhatunk a külső SELECT-re, ezeket az egymásba skatulyázott SELECT-eknek nevezzük.

A belső lekérdezés jellege alapján 2 esetet különböztethetünk meg.

  1. A belső lekérdezés egyetlen értékkel tér vissza. Ez a legegyszerűbb eset, ugyanis ilyenkor minden a hagyományos módon történik, azzal a különbséggel, hogy a feltételként megadott kifejezésben a belső lekérdezés által szolgáltatott értéket használja fel a rendszer.
    Példa: Listázzuk ki azokat a dolgozókat, akiknek az átlagnál kisebb a fizetése.
DOLGOZO(id, nev, szulev, fizetes) SELECT nev, fizetes FROM dolgozo WHERE fizetes < (SELECT AVG(fizetes) FROM dolgozo);
  1. A belső lekérdezés egy listával tér vissza. Ekkor olyan feltételeket adhatunk meg, amelyek a belső lekérdezés által szolgáltatott oszlop adatait használja fel.
    A belső lekérdezés eredménylistáját kezelhetjük az IN, ANY, ALL illetve EXISTS predikátumokkal. Példa: Listázzuk ki azokat a tanulókat, akik nem kapnak segélyt.
TANULO(azon, nev, osztaly) SEGELY(azon, segely) SELECT nev, osztaly FROM tanulo WHERE azon NOT IN (SELECT azon FROM segely);

Predikátumok:

  1. <oszlopkifejezés> [NOT] IN <belső lekérdezés>
    Az <oszlopkifejezés> paraméterben megadott kifejezés értékéről fogja eldönteni, hogy szerepel-e a belső lekérdezés eredményei között. Ha szerepel akkor a feltétel értéke igaz, ha nem szerepel, akkor hamis lesz. A NOT kulcsszó hatására fordítva kell értelmezni a feltételt.

  2. [NOT] <oszlopkifejezés> <reláció> ALL|ANY <belső lekérdezés>
    Itt az <oszlopkifejezés> paraméterben megadott kifejezés értékére vonatkozóan azt fogja vizsgálni, hogy a megadott reláció teljesül-e a belső lekérdezés eredményeire. Ha az ALL kulcsszót használjuk, a feltétel akkor lesz igaz, ha a reláció az oszlop minden elemére teljesül, míg az ANY használatakor elegendő egyetlen elemre teljesülnie. A NOT kulcsszó itt is a feltétel ellentettjét jelenti.

  3. [NOT] EXISTS <belső lekérdezés>
    Az vizsgálja, hogy a keletkezett reláció üres vagy sem. Ehhez a vizsgálathoz az EXISTS kulcsszót kell használnunk, amit természetesen a NOT módosíthat.

Feladatok

I. feladat:

Táblák: sql

dolgozok

id nev kor fizetes osztaly vezeto_id
1 Kovács János 30 200000 1 3
2 Szabó István 25 180000 1 3
3 Nagy Zoltán 40 250000 2 null
4 Tóth Mária 28 220000 2 1
5 Kiss Péter 35 200000 1 2

osztalyok

id nev atlag_fizetes
1 Értékesítés 210000
2 Fejlesztés 230000

Feladatok:

  1. Keresse meg azokat a dolgozókat, akiknek a fizetése magasabb, mint az átlagos fizetés az Értékesítés osztályon. A listában jelenjen meg a dolgozó neve és fizetése, ábécé sorrendben.
  2. Keresse meg azokat a dolgozókat, akiknek a fizetése a legmagasabb az osztályon, ahol dolgoznak. A listában jelenjen meg a dolgozó neve, fizetése és az osztály. A dolgozók ábécé sorrendben jelenjenek meg!
  3. Keresse meg azokat a dolgozókat, akiknek a fizetése magasabb, mint az átlagos fizetés a cégben! A listában jelenjen meg a dolgozó neve és fizetése!
  4. Keresse meg azokat a dolgozókat, akiknek a koruk megegyezik a legfiatalabb dolgozó korával. A listában jelenjen meg a dolgozó neve és kora!
  5. Keresse meg azokat a dolgozókat, akiknek a fizetése a legmagasabb a cégben. A listában jelenjen meg a dolgozó neve és fizetése!

II. Feladat:

Járatok adatbázis

A jaratok tábla szerkezete

Név Típus Null?
SZAM NUMBER(3) NOT NULL
INDULAS NUMBER(4) NOT NULL
ERKEZES NUMBER(4) NOT NULL
HONNAN CHAR(3) NOT NULL
HOVA CHAR(3) NOT NULL
NAPOK CHAR(7)

A jaratok tábla tartalma

SZAM INDULAS ERKEZES HONNAN HOVA NAPOK
123 1152 1436 001 002 hksc-sv
111 1023 1145 002 001 hkscp-v
112 1535 1643 001 003 hkscpsv
113 2032 2115 003 001 hks-psv
114 1322 1423 003 004 -ks-p—
115 1415 1510 001 003 hkscpsv

A palyaudvar tábla szerkezete

Név Típus
KOD CHAR(3)
VAROS CHAR(25)
DIJ NUMBER(5)

A pályaudvar tábla tartalma

KOD VAROS DIJ
001 Budapest 5000
002 Prága 5000
003 Varsó 8000
004 Párizs 10000
005 London 12000

A szamlak tábla szerkezete

Név Típus Null?
RKOD CHAR(3) NOT NULL
OSSZEG NUMBER(5) NOT NULL
KELT DATE
SZLASZAM CHAR(10)
ROGZITO CHAR(30) NOT NULL

A szamlak tábla tartalma

RKO OSSZEG KELT ROGZITO SZLASZAM
001 10000 1999-10-08 kovacs 99/M182
003 30000 1999-10-08 NAGY 99/R436
001 11328 1999-12-28 Virag 99/M183
002 2356 2000-01-13 Lakatos A. 00/M182
002 23560 2000-02-09 Virag 00/M011
002 48000 2000-09-11 Hegyi 00/M032
003 42000 2001-06-12 Magyar Bela 01/R136
004 9364 2001-07-30 Kiss Edit 01/R658
004 12000 2001-08-28 Tóth Ádám 01/R200

jaratok.sql

A következő feladatokat oldja meg belső lekérdezéssel:

  1. Listázza azoknak a pályaudvaroknak a kódját és városát, amelyekhez egyáltalán nincs számla (nem szerepelnek a szamlak táblában).
  2. Mely járatok érkeznek később, mint az adott honnan kódhoz tartozó átlagos érkezési idő?
  3. Milyen járatszámmal és mikor indítanak járatot azok a pályaudvarok, amelyek 20 000 Ft-nál nagyobb számlát küldtek?
  4. Találja meg minden pályaudvarhoz a legutolsó (legkésőbbi) számla keltezését és az összegét — a belső lekérdezés adja meg a maximum keltet.