2012. április 13. TARTALOM

Hasonló dokumentumok
Adatbázis használat I. 2. gyakorlat

KENDE MÁRIA NAGY ISTVÁN: Oracle Példatár(SQL-PL/SQL) Házi feladatok a 3.gyakorlathoz: 1. fejezet: Egyszerű lekérdezések

Adatbázis használat I. 2. gyakorlat

1.1. Feladat Listázza ki a 20-as részleg dolgozóinak nevét, belépési idejét, foglalkozását a nevek szerint csökkenően rendezve.

Adatbázis használat I. 1. gyakorlat

2007. február 25. TARTALOM

Oracle Példatár (SQL-PL/SQL)

ADATBÁZIS-KEZELÉS FÉLÉVES FELADAT

Adatbázis-kezelés. alapfogalmak

NORMALIZÁLÁS. Funkcionális függés Redundancia 1NF, 2NF, 3NF

Adatbáziskezelés. Indexek, normalizálás NZS 1

ADATBÁZIS HASZNÁLAT I. 4. gyakorlat

AB1 ZH mintafeladatok. 6. Minősítse az állításokat! I-igaz, H-hamis

Adatmodellezés. 1. Fogalmi modell

Adatbázisok gyakorlat

6. Gyakorlat. Relációs adatbázis normalizálása

BGF. 4. Mi tartozik az adatmodellek szerkezeti elemei

INFORMATIKA ÁGAZATI ALKALMAZÁSAI. Az Agrármérnöki MSc szak tananyagfejlesztése TÁMOP /1/A

ADATBÁZIS-KEZELÉS. Relációs modell

Adatbázisok I. Definíció: DDL: - objektum létrehozás CREATE - objektum megszüntetés DROP - objektum módosítás ALTER

Adatbázisok. 8. gyakorlat. SQL: CREATE TABLE, aktualizálás (INSERT, UPDATE, DELETE), SELECT október október 26. Adatbázisok 1 / 17

ADATBÁZISOK gyakorlat: SQL 2. rész SELECT

Adatbázisok. 9. gyakorlat SQL: SELECT október október 26. Adatbázisok 1 / 14

Adatbázisok I. Jánosi-Rancz Katalin Tünde 327A 1-1

7. előadás. Karbantartási anomáliák, 1NF, 2NF, 3NF, BCNF. Adatbázisrendszerek előadás november 3.

RELÁCIÓS ADATBÁZISSÉMÁK. Egyed-kapcsolat modellről átírás

Adatbázis-lekérdezés. Az SQL nyelv. Makány György

Adatbázis rendszerek Ea: A rendes állapot. Normalizálás

Csima Judit október 24.

Adatbázisok elmélete 12. előadás

Relációs adatbázisok tervezése ---2

Adatbázis, adatbázis-kezelő

Adatbázisok gyakorlat

Tartalomjegyzék. Tartalomjegyzék 1. Az SQL nyelv 1 Az SQL DDL alapjai 2

SQL DDL-2 (aktív elemek) triggerek

Gyakorlás: Hozzunk létre egy Alkalmazottak táblát AZO szám, Részleg szöveg, Munkakör szöveg és BelépésDátuma dátum típussal.

SQL. Táblák összekapcsolása lekérdezéskor Aliasok Allekérdezések Nézettáblák

SELECT DISTINCT deptno FROM emp; (distinct) SELECT STATEMENT HASH UNIQUE TABLE ACCESS FULL EMP

SQL PÉLDATÁR. készült a PTE TTK Iskolai informatika III. kurzus teljesítésére

Többtáblás lekérdezések megjelenítése

ADATBÁZISOK I. Az esetleges hibákat kérlek a csongor@csongorbokay.com címen jelezd! Utolsó módosítás: március 20.

Bevezetés: az SQL-be

Adatbázis rendszerek Ea: A rendes állapot. Normalizálás

Adatbázis Rendszerek II. 3. SQL alapok

KOVÁCS BÉLA, MATEMATIKA I.

2006. május 1. TARTALOM

Több felhasználó párhuzamosan olvashatja, bővítheti, módosíthatja és törölheti az adatokat Az adatok konzisztenciájának és biztonságának biztosítása

7. Előadás tartalma A relációs adatmodell

ADATBÁZISOK, 2018 ősz

Adatbázis használat I. 5. gyakorlat

Mezők viszonya a relációs adatbázis tábláiban

Adatbázis rendszerek. dr. Siki Zoltán

Adatmodellezés, alapfogalmak. Vassányi István

Adatbázisrendszerek. Karbantartási anomáliák, 1NF, 2NF, 3NF, BCNF, 4NF, 5NF március 13.

Programozás. Adatbázis-kezelés (alapok) Fodor Attila

Relációs adatbázisok tervezése ---1

7. előadás. Karbantartási anomáliák, 1NF, 2NF, 3NF, BCNF, 4NF, 5NF. Adatbázisrendszerek előadás november 7.

Adatbázis-kezelés alapjai 1. Ea: Infó Mátrix. Lehet, nem lehet

A SELECT működése. Ttanar tábla: Tdiak tábla:

T Adatbázisok-adatmodellezés

ADATBÁZISOK, 2017 ősz

Relációs algebra áttekintés és egy táblára vonatkozó lekérdezések

ADATBÁZISOK. 4. gyakorlat: Redundanciák, funkcionális függőségek

ADATBÁZIS-KEZELÉS Demetrovics Katalin

A relációs adatmodell

2012. április 27. TARTALOM

Lekérdezések az SQL SELECT utasítással

ADATBÁZISKEZELÉS ADATBÁZIS

LOGISZTIKAI ADATBÁZIS RENDSZEREK UNIÓ, ALLEKÉRDEZÉSEK

SQL DDL-1: táblák és megszorítások

ALAPOK. 0 és 255 közé eső számértékek tárolására. Számértékek, például távolságok, pontszámok, darabszámok.

Több tábla összekapcsolásán alapuló lekérdezések. Copyright 2004, Oracle. All rights reserved.

ADATBÁZIS-KEZELÉS. 1. Alapfogalmak

Adatbázis rendszerek. 4. előadás Redundancia, normalizálás

ABR ( Adatbázisrendszerek) 2. Előadás : Műveletek a relációs modellben

SQL jogosultság-kezelés. Privilégiumok Grant és Revoke Grant Diagrammok

Adatbázisok-1 előadás Előadó: dr. Hajas Csilla

Adatbázis Rendszerek I. 10. SQL alapok (DML esettanulmány)

Adatbázisok. 1. gyakorlat. Adatmodellezés október október 1. Adatbázisok 1 / 42

Informatikus informatikus Térinformatikus Informatikus É 1/6

Lekérdezések az SQL-ben 1.rész

Lekérdezések az SQL-ben 1.rész

Adatbázismodellek. 1. ábra Hierarchikus modell

INFORMATIKAI ALAPISMERETEK

SQL. 1.rész. 1.elıadás // Adatbázisok-1 elıadás // Ullman-Widom (Stanford) tananyaga alapján // Hajas Csilla (ELTE IK) 1

Gazdasági informatika II (SZIE GTK GVAM 1. évfolyam) 2009/2010. tanév 2. félév

8. előadás. normálformák. Többértékű függés, kapcsolásfüggés, 4NF, 5NF. Adatbázisrendszerek előadás november 10.

SQL*Plus. Felhasználók: SYS: rendszergazda SCOTT: demonstrációs adatbázis, táblái: EMP (dolgozó), DEPT (osztály) "közönséges" felhasználók

A gyakorlat során MySQL adatbázis szerver és a böngészőben futó phpmyadmin használata javasolt. A gyakorlat során a következőket fogjuk gyakorolni:

Adatbázis rendszerek SQL nyomkövetés

Adatmodellek. 2. rész

5.előadás: Adatbázisok-I. dr. Hajas Csilla (ELTE IK)

A könyv tartalomjegyzéke

Adatbázisok elmélete 11. előadás

Adatbázisok* tulajdonságai

Csima Judit november 15.

SQL haladó. Külső összekapcsolások, Csoportosítás/Összesítés, Beszúrás/Törlés/Módosítás, Táblák létrehozása/kulcs megszorítások

Adatbázisok 1. Kósa Balázs gyakorlata alapján Készítette: Nagy Krisztián. 1. gyakorlat

ABR ( Adatbázisrendszerek) 1. Előadás : Műveletek a relációs medellben

Példa Többértékű függőségek, 4NF, 5NF

Átírás:

KENDE MÁRIA - NAGY ISTVÁN SQL BEVEZETŐ FELADATGYŰJTEMÉNY TARTALOM Előszó... 2 Megjegyzés... 2 0. Foglalkozás Adatbázis tervezés... 3 1. Foglalkozás Az SQL használatának alapjai, Egyszerű lekérdezések... 11 2. Foglalkozás Egytáblás csoportosító lekérdezések... 14 3. Foglalkozás Többtáblás lekérdezések, allekérdezések... 23 4. Foglalkozás Interaktív környezet... 31 5. Foglalkozás Adattáblák létrehozása, módosítása, tranzakciók, megszorítások... 35 6. Foglalkozás Nézettáblák, felső-n analízis, ROWNUM... 51 7. Foglalkozás SQL összefoglaló feladatsorok... 68 8. Foglalkozás Adatbázis-adminisztrátori ismeretek, jogosultság-kezelés... 101 Mellékletek Árnyék-objektumok... 105 Hierarchikus szerkezetű adattáblák feldolgozása... 107 Irodalom... 111 2012. április 13.

ELŐSZÓ E feladatgyűjtemény a tankönyvek (lásd az Irodalomban) kiegészítését, az "Adatbázis-kezelés" gyakorlatokra való önálló felkészülés további támogatását szolgálja. Az egyes Foglalkozások anyagában természetesen ismertnek tételezzük fel, és ezért fel is használjuk a tankönyvekben részletesen tárgyalt, valamint a korábbi Foglalkozásokban bemutatott anyagot. A megoldásoknál célszerű betartani a "02_Mire ügyeljünk.doc" file-ban írottakat. A feladatok az alábbi emp és dept táblákra vonatkoznak: >> Az emp tábla (14 soros): EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- ---------- --------- ---------- ---------- ---------- ---------- ---------- 7839 KING PRESIDENT 1981-11-17 5000 10 7698 BLAKE MANAGER 7839 1981-05-01 2850 30 7782 CLARK MANAGER 7839 1981-06-09 2450 10 7566 JONES MANAGER 7839 1981-04-02 2975 20 7654 MARTIN SALESMAN 7698 1981-09-28 1250 1400 30 7499 ALLEN SALESMAN 7698 1981-02-20 1600 300 30 7844 TURNER SALESMAN 7698 1981-09-08 1500 0 30 7900 JAMES CLERK 7698 1981-12-03 950 30 7521 WARD SALESMAN 7698 1981-02-22 1250 500 30 7902 FORD ANALYST 7566 1981-12-03 3000 20 7369 SMITH CLERK 7902 1980-12-17 800 20 7788 SCOTT ANALYST 7566 1987-04-19 3000 20 7876 ADAMS CLERK 7788 1987-05-23 1100 20 7934 MILLER CLERK 7782 1982-01-23 1300 10 >> A dept tábla (4 soros): DEPTNO DNAME LOC ---------- -------------- ------------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON A táblák értelmezése: Az emp tábla a feladatokban szereplő vállalat dolgozóinak adatait tartalmazza. E tábla oszlopneveire a következő magyar nevekkel fogunk hivatkozni: empno a dolgozó azonosítója, ename a neve, job a munkaköre, mgr a főnöke azonosítója, hiredate a belépésének dátuma, sal a fizetése, comm a jutaléka, deptno a részlegének azonosítója. A dept tábla a vállalat részlegeinek adatait tartalmazza. E tábla oszlopneveire a következő módon fogunk hivatkozni: deptno a részleg azonosítója, dname a neve, loc a telephelye. MEGJEGYZÉS E feladatgyűjtemény pdf formátumban a www.orakulum.com honlapon található az "Adatbáziskezelés" témakör kiválasztása után az "AKT (Adatbázis-Kezelés Technológiája)" menüpont kijelölésével a Labor almenüpontban letölthető 413_Labor alkönyvtárban, ahol egyéb (részben ebben az anyagban is hivatkozott) kiegészítő oktatási anyagok is találhatók. (E file az Acrobat cég www.acrobat.com honlapjáról ingyenesen letölthető, és a saját gépen telepíthető AcrobatReader programja segítségével olvasható.) Jelen dokumentum szerzői jogi védelem alatt áll, kizárólag az egyéni felkészülés céljára használható. Csak számítógépen olvasható, sem a teljes dokumentum, sem annak bármely része nem nyomtatható ki, nem másolható le, illetve nem adható ki a szerzők írásos engedélye nélkül. #11_SQL Feladatgyűjtemény (30) - 2 -

0. Foglalkozás Adatbázis Tervezés Részletesebben lásd [1]: II. rész, 7. fejezet RELÁCIÓ-ALGEBRAI ÁTTEKINTÉS (Jelölések, definíciók) Elemek: a, b, c,... Halmazok: A, B, C,... Halmaz megadása (elemei felsorolásával): pl. A = {a, b, c}, ekkor pl. a A, azaz a eleme A-nak Halmaz megadása (az elemek tulajdonságának megadásával): pl. B = { x x >= 50, x < 200 } A halmazokat rendezetleneknek tekintjük (esetenként a rendezetlen halmaz kifejezést is használjuk), vagyis bennük az elemek sorrendje tetszőleges, például {a, b, c} = {c, b, a}. A gyakorlatban a legtöbb csoportosítás ilyen, például Péter barátai: { Laci, Zoli, Attila }. Részhalmaz: Egy B halmaz részhalmaza egy A halmaznak, ha B minden eleme az A-nak is eleme. Jelölése: B A. Például {c, a} {a, b, c}. Rendezett halmaz (más néven vektor): pl. q = a, b, c A rendezett halmazokban az elemek sorrendje kötött, a sorrendjük megváltoztatásával már egy másik rendezett halmazhoz jutunk, így nyílván a, b, c c, b, a. Ilyen például egy pont helyvektora valamely koordinátarendszerben, vagy a vezeték név kereszt név páros. (Nyilván nem mindegy, hogy valakinek Gábor Miklós, vagy Miklós Gábor a neve.) Halmazok Descartes szorzata: Például A = {a, b, c} és B = {0, 1} esetén A B = { a, 0, a, 1, b, 0, b, 1, c, 0, c, 1 }. A Descartes szorzat tehát egy rendezett elempárosokat tartalmazó halmaz. A halmazok Descartes szorzatát értelemszerűen kiterjeszthetjük kettőnél több tényezőre is, ekkor persze már nem párosokról, hanem hármasokról, négyesekről, vagy általánosabban n-esekről beszélünk. Ezeket az n-eseket az adatbázis-kezelésben rekordoknak nevezzük. Attribútumok (tulajdonság-halmazok): A, B, C,... Tehát az attribútumok maguk is halmazok. Attribútum halmaz: pl. Q = { A, B, C, D, E, F, G } Funkcionális függőség: pl. f = { A, B } { C, D, E } Gyakorlati példa f dolgozó = {NÉV, OSZTÁLY} {MUNKAKÖR, MUNKAKÖRI_FIZETÉS, JUTALÉK} A funkcionális függőségeket (melyek tulajdonképpen többváltozós, többértékű függvények) a gyakorlatban röviden csak függőségeknek szoktuk nevezni. Kulcs (elsődleges kulcs, primary key) néven nevezzük a függőség baloldalán álló (úgynevezett elsődleges) attribútumok összességét. Ha a kulcs csak egyetlen attribútumból áll, akkor egyszerű kulcsról, egyébként összetett kulcsról beszélünk. A függőség jobboldalán álló attribútumokat másodlagos attribútumoknak nevezzük. A fenti példában tehát a K fdolgozó = {NÉV, OSZTÁLY} attribútumhalmaz kulcs, míg a Q fdolgozó = {MUNKAKÖR, MUNKAKÖRI_FIZETÉS, JUTALÉK} a másodlagos attribútumok halmaza, és az f dolgozó, mint többváltozós, többértékű függvény azt jelenti, hogy a NÉV, és az OSZTÁLY #11_SQL Feladatgyűjtemény (30) - 3 -

attribútumok együttesen meghatározzák a MUNKAKÖR, a MUNKAKÖRI_FIZETÉS, és a JUTALÉK attribútumok mindegyikét külön-külön. Tehát a fenti függőség helyett ekvivalens módon megadhatjuk az alábbi függőségek együttesét: f dolgozó1 = {NÉV, OSZTÁLY} {MUNKAKÖR} f dolgozó2 = {NÉV, OSZTÁLY} {MUNKAKÖRI_FIZETÉS} f dolgozó3 = {NÉV, OSZTÁLY} {JUTALÉK} Ennek alapján fogjuk az alábbiakban értelmezni a függőségek ekvivalens felbontását és egyesítését. Függőségek ekvivalens egyesítése és felbontása: Két függőség ekvivalens módon egyesíthető, ha baloldaluk azonos. Ekkor az egyesített függőség jobboldala mindkét függőség jobboldalának attribútumait tartalmazza. Az egyesítés jele: Például f = { A, B } { C, D, E } és g = { A, B } { F, G } esetén: f g = { A, B } { C, D, E, F, G } Minden függőség ekvivalens módon bontható fel olyan függőségek halmazára, melyekben a baloldalak megegyeznek az eredeti függőség baloldalával, a jobboldalak pedig az eredeti függőség jobboldalának egy-egy attribútumát tartalmazzák. Az egyesíthetőség és felbonthatóság fenti ekvivalenciái a gyakorlatban azt jelentik, hogy mivel elvben mindegy, hogy például az f g függőséget, vagy az f, g függőségpárost használjuk, ezért gyakorlati szempontok alapján választhatunk. Relációséma az f függőség fölött: R f A, B, C, D, E = A B C D E A relációséma a pontos algebrai jelentése szerint tehát a benne szereplő attribútumoknak a megadásuk sorrendjében vett Descartes-szorzata, vagyis halmaz, melynek elemei attribútum-érték n-esek, vagyis rekordok. A relációsémát a továbbiakban azonosítani fogjuk egy olyan adattáblával, melynek oszlopnevei a relációséma attribútumai, a sorai pedig a relációséma rekordjai. Mivel az egyes attribútumok (tulajdonság-halmazok) a megengedett értékek mindegyikét tartalmazzák, ezért a relációséma ebben az algebrai értelemben az összes lehetséges tulajdonság érték összes lehetséges csoportosítását tartalmazza, ami nyilván sokkal több nemcsak annál, ami egy adott pillanatban egyáltalán lehetséges, hanem annál is, ami valaha előfordulhat. Például egy ember lehet 1 m magas és 18 kg testsúlyú (kb. 6 éves korában), és lehet 2 m-es, 150 kg-os felnőttként, de egész biztos nem lehet 1 m-es és 150 kg-os. A fentiek miatt a relációsémát a gyakorlatban inkább egy adattábla szerkezetének (más néven sémájának) megadására használjuk, és az őt reprezentáló adattábla helyett a gyakorlatban ténylegesen tárolt rekordokat tartalmazó adattáblával fogunk dolgozni. Ennek algebrai modelljét fogjuk a továbbiakban relációnak nevezni, mely tehát algebrailag nem más, mint a relációséma részhalmaza, gyakorlatilag pedig a ténylegesen feltöltött adattábla. Reláció az f függőség fölött: r f A, B, C, D, E R f A, B, C, D, E Gyakorlati példa: Jelölje dolgozó az f dolgozó függőség fölötti relációt. E reláció egy lehetséges értéke ekkor: dolgozó NÉV, OSZTÁLY, MUNKAKÖR, MUNKAKÖRI_FIZETÉS, JUTALÉK = { Tóth Pál, TMK, asztalos, 60000, 30000, Kis Jolán, Bérosztály, könyvelő, 80000, 0, Kis Elemér, Áruforgalmi osztály, eladó, 50000, 60000 } A relációk elemeit rekordoknak is nevezzük, és a relációkat a gyakorlatban olyan adattáblának nevezett táblázatokban ábrázoljuk, ahol a rekordok alkotják a sorokat, az attribútumok rekordbeli értékei pedig az oszlopokat. Egy relációsémában, illetve relációban #11_SQL Feladatgyűjtemény (30) - 4 -

a rajta értelmezett függőség elsődleges, azaz kulcs- és másodlagos attribútumait a függőségnél mondottakkal azonos módon használjuk. Valamely r reláció rekordjainak attribútumkészletét (azaz tulajdonsághalmazát) ki tudjuk terjeszteni egy s reláció attribútumaira, ha az s valamely K s kulcsának minden attribútuma az r-nek is attribútuma. Ekkor a K s kulcsot az r reláció idegen kulcsának is nevezzük (lásd az alábbi mintapéldát), ha teljesül, hogy 1. a K s -beli attribútumok minden értékegyüttese az s-ben legfeljebb egyszer fordul elő, és 2. a K s -beli attribútumok minden r-beli értékegyüttese az s-ben is előfordul. Ezt nevezik idegen kulcs megszorításnak, az s és r relációk közötti kapcsolatot pedig 1:N kapcsolatnak, mivel minden s-beli kulcs az r relációban N-szeresen fordul elő, ahol N 0. Adatbázis: Általános értelemben adatbázisnak nevezzük valamely nyilvántartási feladatban fontosnak tekintett tulajdonságú tárolt objektumok (adat- és nézettáblák, jogosultságok, tárolt alprogramok, triggerek, stb.) összességét, szűkebb értelemben egy adott alkalmazáshoz tartozó adattáblák összességét. A nem megfelelő szerkezetű adattárolás több veszélyt is rejt magában (ezeket adatbázisanomáliáknak nevezzük, lásd e foglalkozási anyag végén), mely veszélyek elhárítása érdekében egy normalizálásnak nevezett adatbázis-tervezési eljárást használunk (lásd az alábbi mintapéldát). ADATBÁZIS TERVEZÉS (Vázlatos áttekintés) Az adatbázis tervezés, vagyis a normalizálás során a tárolni kívánt tulajdonságok (attribútumok) összességét kijelölő kezdeti adatbázis sémából (az úgynevezett ősmodellből), valamint az e tulajdonságok között felismert összefüggésekből (a függőségekből) indulunk ki. A függőségeken elvégzett transzformáció-sorozat (vagyis a tényleges normalizálás) eredményeként kapott, úgynevezett eredmény függőségek mindegyikéhez egyértelműen hozzárendelt eredmény relációsémák összessége alkotja az eredmény adatbázis sémát. Végül az eredmény relációsémákat reprezentáló adattáblák együttesen alkotják az eredetileg kijelölt nyilvántartási feladat adatbázisát. A normalizálás egyes lépései során a normalizálás adott szintjén létező függőségekre vonatkozóan bizonyos követelményeket fogalmazunk meg. Ezeket a követelményeket normálformáknak nevezzük. Mi a normalizálás folyamatát négy; az első, a második, a harmadik, és a Boyce- Codd normálforma fázisain keresztül valósítjuk meg. Ezek jelölése; 1NF, 2NF, 3NF és BCNF. Az alábbiakban az ezekben megfogalmazott követelményeket foglaljuk össze: 1.) Minden attribútum egyszerű (vagyis csak egyetlen adatot tartalmaz) [1NF]. 2.) A másodlagos attribútumok mindegyikét a kulcsattribútumok csak együttesen határozzák meg (vagyis nincs részleges függés) [2NF]. 3.) A másodlagos attribútumok egymástól (funkcionálisan) függetlenek (vagyis nincs belső függés) [3NF]. 4.) A kulcsattribútumoknak nincs olyan részhalmaza, mely más kulcs- vagy másodlagos attribútumoktól (funkcionálisan) függne (vagyis nincs kulcstörés) [BCNF]. A magasabb normálformákban értelemszerűen teljesülniük kell az alacsonyabb normálformákban megfogalmazott követelményeknek. Az alábbi mintapéldában a feladat egy olyan adatbázis séma megtervezése lesz, melyben egy ősmodellből (kiindulási adatbázis sémából) el kell jutni a BCNF normálformában megfogalmazott követelményeket is teljesítő (BCNF alakú) adatbázis sémához. #11_SQL Feladatgyűjtemény (30) - 5 -

Az adatbázis-tervezés első lépése tehát a tárolni kívánt tulajdonságok (attribútumok) összességének (az ősmodell) kijelölése. Ez egy kreatív, intellektuális tevékenység, mely alapos körültekintést igényel, ám a tervezés eljárásának szempontjából önkényes. Az ősmodellben már minden attribútum rögzített (bár esetleg összetett) adattípussal rendelkezik, vagyis az ősmodellel kijelöltük a tárolni kívánt objektum típusát, az ősobjektumtípust. Felmerülhet ezek után a kérdés, miért nem ezt implementáljuk, miért van szükség további lépésekre. A válasz lényege, hogy el akarjuk kerülni az úgynevezett adatbázis-anomáliákat (lásd alább!), vagyis az adatvesztést és az inkonzisztenciát (tartalom-ellentmondást). A tervezési folyamat, a normalizálás első, és egyben legfontosabb lépése, az attribútumok közötti összefüggések, az úgynevezett függőségek felismerése. Ez is intellektuális, nem automatizálható lépés, ám már semmiképpen nem önkényes. Az adattárolás céljának, valamint a tárolni kívánt attribútumoknak (tulajdonságoknak) az ismeretében, a függőségek felírása tulajdonképpen az általunk létrehozni kívánt zárt világ belső kapcsolatainak, összefüggéseinek feltérképezését jelenti. Maga a normalizálás a felírt függőségeknek a normálformák követelményei szerinti (lényegében mechanikus) transzformációját jelenti, melynek során (és ez nagyon lényeges!) automatikusan (!) elkülönülnek az ősmodell ősobjektumtípusából az adatmodell célszerű építőkövei, az elemi objektumtípusok, melyeket relációsémáknak is nevezünk, és amelyeknek implementációi maguk az adattáblák. Egyszerűbb feladatok esetén ezek az elemi objektumtípusok (relációsémák, adattáblák), szinte ránézésre elkülöníthetők (Raktár, Beszállítók, Vevők, Rendelések, stb. táblák), ám egy összetett feladat esetén csak a normalizálási folyamat automatizmusa adhat garanciát az üzembiztosan használható adatmodell létrehozására. Végül egy fontos gyakorlati javaslat. Mind a függőségek feltérképezésénél, mind a normalizáció transzformációs lépéseinél célszerű az összes lehetséges ekvivalens függőség-egyesítést elvégezni (lásd feljebb!). Ez a gyakorlatban azt jelenti, hogy kevesebb adattáblát kell használnunk, elvileg pedig azt, hogy ugyanannak az objektumtípusnak egyetlen relációsémában tartjuk az attribútumait. EGY ADATBÁZIS-TERVEZÉSI MINTAPÉLDA Legyen egy adatbázis sémája: dolgozó NÉV, OSZTÁLY, MUNKAKÖR, MUNKAKÖRI_FIZETÉS, JUTALÉK, FŐNÖK, TELEPHELY_CÍME, ahol feltételezzük, hogy a.) a NÉV és az OSZTÁLY adatok csupán együtt azonosítják egyértelműen a dolgozót, b.) egy OSZTÁLY egy telephelyen található. Alakítsa át ezt az adatbázis sémát BCNF alakra. (Mutassa be a tervezés folyamatát, és adja meg az elsődleges és az idegen kulcsokat is.) MEGOLDÁS 1. lépés (A tárolandó attribútumok kijelölése az ősmodell relációsémája) dolgozó NÉV, OSZTÁLY, MUNKAKÖR, MUNKAKÖRI_FIZETÉS, JUTALÉK, FŐNÖK, TELEPHELY_CÍME 2. lépés (A függőségek felismerése) A függőségeket részben az attribútumok szövegesen megadott kapcsolatai, részben a józan ész megfontolása alapján ismerjük fel. #11_SQL Feladatgyűjtemény (30) - 6 -

a.) Az a NÉV és az OSZTÁLY adatok csupán együtt azonosítják egyértelműen a dolgozót kapcsolatból az alábbi függőség következik: f dolgozó = { NÉV, OSZTÁLY } { MUNKAKÖR, MUNKAKÖRI_FIZETÉS, JUTALÉK, FŐNÖK, TELEPHELY_CÍME } b.) Az egy OSZTÁLY egy telephelyen található kapcsolatból következik: f osztályok = { OSZTÁLY } { TELEPHELY_CÍME } Mivel a NÉV és az OSZTÁLY egyértelműen azonosítják a dolgozót, így a józan ész alapján nyilván felírható f főnök = { OSZTÁLY } { FŐNÖK }, a fenti két függőség pedig egyesíthető, hiszen a baloldaluk azonos. Így kapjuk: f osztályok1 = { OSZTÁLY } { FŐNÖK, TELEPHELY_CÍME } c.) A józan ész alapján felírható az alábbi függőség: f munkakörök = { MUNKAKÖR } { MUNKAKÖRI_FIZETÉS } Megjegyezzük, hogy a tervezés tehát az összes függőség felismerésével kezdődik, vagyis a további lépésekben új függőség nem "keletkezhet" (csak a már meglévők transzformálódhatnak a normalizálás lépéseinek megfelelően). A felismert függőségek közül azonban nem feltétlenül szükséges mindegyiket felhasználnunk a tervezés további részében, hiszen lehetnek közöttük olyanok, melyek egymás alternatíváinak tekinthetők (és az alkalmazás egyéb szempontjai alapján döntünk az egyik, vagy a másik mellett), és lehetnek olyanok is, amelyek az adott alkalmazás szempontjából érdektelenek. Ezt a redukciót azonban kellő körültekintéssel kell végeznünk, mert információvesztéssel járhat. 3. lépés (A függőségek normalizálása) A normalizálás folyamatában tulajdonképpen egymásután vizsgáljuk a függőségeket, egy adott függőség megítélése során azonban figyelembe kell venni az attribútumaira vonatkozó többi függőséget is (például az éppen vizsgált függőségnek egy másik nem belső függősége-e, stb.) 3.1. lépés (az f dolgozó függőség vizsgálata) 1NF: az f dolgozó 1NF-ben van, mivel nincs benne összetett attribútum, 2NF: az f dolgozó nincs 2NF-ben, mivel az f osztályok1 függőség értelmében az f dolgozó függőség másodlagos (a függőség jobboldalán álló) attribútumainak némelyike nem függ az elsődleges attribútumok (a baloldal) mindegyikétől. Az f osztályok1 függőséget kiemelve az f dolgozó függőségből, kapjuk az f dolgozó1 = { NÉV, OSZTÁLY } { MUNKAKÖR, MUNKAKÖRI_FIZETÉS, JUTALÉK } függőséget, mely már nyilvánvalóan 2NF alakban van. 3NF: az f dolgozó1 nincs 3NF-ben, mivel jobboldalán az f munkakör függőség, mint belső függés található. Ezt kiemelve, kapjuk az f dolgozó2 = { NÉV, OSZTÁLY } { MUNKAKÖR, JUTALÉK } függőséget, mely már 3NF alakban van. BCNF: a BCNF feltétele, hogy a függőség 3NF-ben legyen, továbbá a baloldalának egyetlen valódi részhalmaza se függjön egyetlen elsődleges, vagy másodlagos attribútumtól. Ez utóbbi az f dolgozó2 függőség esetén azért teljesül, mert az attribútumok megadott (vagy feltételezhető) tulajdonságaiból ilyen függések nem következnek. #11_SQL Feladatgyűjtemény (30) - 7 -

3.2. lépés (az f osztályok1 függőség vizsgálata) 1NF: az f osztályok1 1NF-ben van, mivel nincs benne összetett attribútum, 2NF: az f osztályok1 2NF-ben is van, mivel a másodlagos attribútumok mindegyike az elsődleges attribútumok mindegyikétől függ (hiszen a baloldalon csak egyetlen attribútum áll). 3NF: az f osztályok1 3NF-ben is van, mivel a másodlagos attribútumok között sem megadott, sem feltételezhető kapcsolat (azaz függőség) nincs. BCNF: mivel az f osztályok1 3NF-ben van, és a baloldalán csak egyetlen attribútum áll, így egyúttal BCNF-ben is van. 3.3. lépés (az f munkakörök függőség vizsgálata) Az f munkakörök függőség már BCNF-ben is van (tehát 1NF-ben, 2NF-ben és 3NF-ben is), mivel a bal- és a jobboldalon is csak egyetlen attribútum áll. 4. lépés (Az eredmény függőségek összefoglalása) Alábbiakban összefoglaljuk a fenti normalizálási folyamat során kapott eredmény függőségeket: f dolgozó2 = { NÉV, OSZTÁLY } { MUNKAKÖR, JUTALÉK } f osztályok1 = { OSZTÁLY } { FŐNÖK, TELEPHELY_CÍME } f munkakörök = { MUNKAKÖR } { MUNKAKÖRI_FIZETÉS } 5. lépés (Az eredmény adatmodell felírása) Az eredmény függőségek alapján az eredmény adatmodell (tehát az eredmény relációsémák, vagyis az adattáblák halmaza), valamint az elsődleges kulcsok és az idegen kulcsok az alábbi módon írhatók fel: dolgozók NÉV, OSZTÁLY, MUNKAKÖR, JUTALÉK, ahol a K dolgozók = { NÉV, OSZTÁLY } attribútum halmaz a dolgozók relációra vonatkozó elsődleges kulcsa, az F osztályok = { OSZTÁLY }, illetve az F munkakörök = { MUNKAKÖR } attribútum halmazok pedig a dolgozók relációnak az osztályok, illetve a munkakörök relációra vonatkozó idegenkulcsai (az elsődleges kulcsattribútumokat aláhúztuk, az idegen kulcsattribútumokat pedig dőlt betüvel jelenítettük meg), osztályok OSZTÁLY, FŐNÖK, TELEPHELY_CÍME, ahol a K osztályok = { OSZTÁLY } attribútum halmaz az osztályok relációra vonatkozó elsődleges kulcsa munkakörök MUNKAKÖR, MUNKAKÖRI_FIZETÉS, ahol a K munkakörök = { MUNKAKÖR } attribútum halmaz a munkakörök relációra vonatkozó elsődleges kulcsa. Ilymódon tehát minden eredmény függőséghez egyértelműen hozzárendeltünk egy relációsémát a függőség attribútumainak összességével. A relációsémákban a szokásoknak megfelően aláhúztuk az elsődleges kulcsok attribútumait. #11_SQL Feladatgyűjtemény (30) - 8 -

ADATBÁZIS-ANOMÁLIÁK A fentiekben áttekintettük az adatbázis-tervezés alapvető lépéseit, fogalmait. Az adatbázismodell 2NF, 3NF és BCNF alakra hozása érzékelhető redundancia-csökkenéssel járt (az 1NF még nem!), és ez összhangban volt eredeti célkitűzésünkkel. A Normalizálás alfejezet bevezetőjében azonban utaltunk arra is, hogy a normalizálással bizonyos rendellenes adatbázisműködéseket is ki szeretnénk zárni. Eljött az ideje annak, hogy mintegy a fejezet lezárásaként áttekintsük e rendellenességeket (más szóval anomáliákat), továbbá egyben azt is megvizsgáljuk, hogy az általunk bevezetett eszközök segítségével e rendellenességek kiküszöbölhetőkké váltak-e. Induljunk ki az 1NF alakból, hiszen az olyan relációsémák, melyek nincsenek 1NF alakban (tehát összetett attribútumokat, azaz ismétlődő csoportokat tartalmaznak) eleve alkalmatlanok arra, hogy adattáblákkal reprezentáljuk. Az alábbiak során tekintsük a korábban már bevezetett KATALÓGUS ISBN, KÖNYV_CÍME, TÉMA, KIADÁSI_ÉV, ÁR, KIADÓ, KIADÓ_CÍME, relációsémát, melyről tudjuk, hogy 2NF alakú (tehát 1NF alakú is), de nem 3NF alakú, és így nem BCNF alakú. Módosítási anomália Módosítási anomáliának nevezzük azt a jelenséget, amikor az adatbázis valamely adatának a megváltoztatása során történő hiba az adatbázis konzisztenciáját (azaz ellentmondásmentességét) veszélyezteti. Tegyük fel, hogy valamelyik kiadó elköltözik, tehát módosítani szeretnénk e kiadó címét. Ha az adatbázisunk modellje a fenti katalógus relációséma, akkor már önmagában kellemetlen, hogy ezt mindazon rekordon el kell végezni, amelyben az adott kiadó szerepelt (ezt a redundancia okozza). Az viszont már az adatbázis konzisztenciáját veszélyezteti, ha ez a módosítási folyamat bármilyen okból (például egy áramkimaradás, vagy rendszerösszeomlás miatt) megszakad, ugyanis így egyszerre szerepelhet az adatbázisban a régi és az új cím. Abban az esetben pedig, ha ez a módosítás nem egy megfelelő SQL utasítással, hanem kézzel (tehát közvetlen adatátírással) történik, akkor még az is előfordulhat, hogy tévesztés miatt különböző címadatok kerülnek az adatbázisba. Könnyen belátható, hogy a redundancia, vagyis a részleges függések, illetve a tranzitív függések megszüntetésével, tehát az adatbázis BCNF alakjában a módosítási anomália veszélye elhárul. Feltehető ezekután a kérdés, hogy egy BCNF alakú adatbázisban a módosítás nem okozhat-e hibát? Természetesen okozhat! Hibás adatot bármikor be lehet vinni egy adatbázisba, ez ellen nincs védelem. Ám egy irredundáns adatbázisban ez nem okoz inkonzisztenciát, ilymódon ha észrevesszük a hibát, könnyen ki tudjuk javítani. Nem az a végzetes baj tehát, ha például egy kiadó címét rosszul írjuk (csak észrevesszük előbb-utóbb), hanem az, ha ez a cím különbözőképpen szerepel. Ezt kijavítani egy nagy adatbázisban (mely erre az adatra nézve nem irredundáns) szinte lehetetlen. Az [1] könyv II. részének 7. fejezetéből átvéve #11_SQL Feladatgyűjtemény (30) - 9 -

Törlési anomália Törlési anomália fordul elő olyankor, amikor valamely fölöslegesnek, vagy hibásnak minősült adat törlése során információvesztés történik. Gondoljunk ismét a fenti katalógus relációsémára. Tegyük fel, hogy a könyvesboltból (melynek ez a katalógusa) kifogy egy olyan könyv, melynek kiadója csak ezzel a könyvvel szerepelt a kínálatban. Nagy baj ez, mivel az által, hogy kitöröltük a könyvet a katalógusból, kitöröltük a kiadójának adatait is, úgyhogy most már rendelni sem tudunk belőle. Mi is okozta ezt a rendellenességet? Láthatóan az, hogy a kiadó adatait együtt tároltuk a könyv adataival. A könyv és a kiadója két különböző objektum, melyek mindegyike fontos az adatbázisban, tehát különböző relációban (külön adattáblában) kell tárolni őket. A külön történő tárolás egy belső függést számolt fel, tehát ennek az anomáliának az elhárításához az adatbázis 3NF alakja szükséges. Bővítési anomália Bővítési anomália következik be olyankor, amikor valamely adat bevitele azért bizonyul lehetetlennek, mert rá vonatkozóan nincs kulcs. Tegyük fel, hogy fenti katalógus relációsémát alkalmazó könyvesbolt vezetője együttműködési szerződést ír alá valamelyik kiadóval. Ezt követően szeretné beírni az adatbázisba ennek a kiadónak az adatait, hogy majd rendelni tudjanak tőlük (tegyük fel, hogy ehhez az adatbázishoz kapcsolódik egy rendeléskezelő program is). Az előbbihez hasonló problémával kell szembenéznie, csak most nem elveszik a cím, hanem már be se tudja írni. Ennek az az oka, hogy a katalógus relációsémájú adatbázis objektumai könyvek, melyeknek az ISBN számuk a kulcsadatuk, így enélkül nem lehet adatot bevinni. Márpedig az új kiadó adataihoz nem rendelhető ISBN szám. A problémát ezúttal is az okozza, hogy egy rekordban két különböző objektum adatait tároljuk, de a rekord kulcsa csak az egyik objektumnak kulcsa. Miután a kiadó független e kulcstól, így az adataival önmagában nem lehet elvégezni a bővítést. A belsőfüggések felszámolása, külön relációséma megalkotása, vagyis az adatbázis 3NF alakra hozása nyilvánvalóan ezt a problémát is megoldja. IRODALOM [1] Kende M. Kotsis D. Nagy I.: Adatbázis-kezelés az Oracle-rendszerben, Panem, 2002. További ajánlott irodalom az adatbázis-tervezéshez Halassy Béla: Az adatbázis-tervezés alapjai és titkai, IDG, 1994. Ullman, J. D., Widom J.: Adatbázis-rendszerek - Alapvetés, Panem, 1998. Ensor, D., Stevenson I.: Oracle-tervezés, Kossuth, 2000. Halassy Béla: Adatmodellezés, Nemzeti tankönyvkiadó, 2002. Békéssy András, Demetrovics János: Adatbázis-szerkezetek, Akadémiai Kiadó, 2005. #11_SQL Feladatgyűjtemény (30) - 10 -

1. Foglalkozás Az SQL használatának alapjai, Egyszerű lekérdezések Részletesebben lásd [2]: 3. melléklet, 1. fejezet, "00-2_Bevezetés az SQL-Plus-ba (Példatár).pdf" file FELADATGYŰJTEMÉNY 1.1. Feladat Írassa ki azon dolgozók munkakörét és fizetését, akiknek fizetése nincs az 1500-2500 USD tartományban. A lista fejléce legyen Név, Munkakör, Fizetés, rendezzen a dolgozók neve szerint. 1.2. Feladat Írassa ki a salesman és a clerk munkakörű azon dolgozók nevét, munkakörét és jövedelmét, akiknek jövedelme nincs az 1500-2500 USD tartományban. A lista fejléce legyen Név, Munkakör, Jövedelem. TOVÁBBI FELADATOK T1.3. Feladat Írassa ki azon dolgozók nevét, munkakörét, fizetését, jutalékát, részleg-azonosítóját, akik 1000 USD-nél többet keresnek, továbbá 1981. március 1. és szeptember 30. között léptek be a vállalathoz. T1.4. Feladat Írja ki azon dolgozók nevét, foglalkozását, fizetését és belépési dátumát, akik 1981-ben léptek be a vállalathoz. A lista legyen belépési dátum szerint rendezve. T1.5. Feladat Írassa ki azon alkalmazottak azonosítóját, nevét, foglalkozását, fizetését és jutalékát, akiknek jutaléka meghaladja a fizetésük 70 %-át. T1.6. Feladat Készítsen listát az összes alkalmazottról úgy, hogy a lista fejléce: Azonosító, Belépési dátum, Név, Foglalkozás, Jutalék, továbbá a Jutalék oszlopban azoknál, akik nem kapnak jutalékot, az a szöveg jelenjen meg, hogy nincs jutalék. T1.7. Feladat Belépési dátum szerint (év.hónap.nap.) listázza a salesman foglalkozású dolgozók azonosítóját, nevét, foglalkozását, hathavi fizetését és hathavi jövedelmét. T1.8. Feladat Listázza azon dolgozók nevét jövedelmét és részlegét, akiknek nevében az "R", vagy az "A" betű szerepel, és jövedelmük (fizetés+jutalék) 1000 és 2500 USD között van. A lista legyen rendezett a részleg szerint, azon belül pedig a foglalkozás szerint. T1.9. Feladat Listázza 1981-től dolgozók nevét, munkakörét, jövedelmét és belépési évszámát elsődlegesen a belépési évszám szerint, másodlagosan a dolgozók neve szerint rendezve. #11_SQL Feladatgyűjtemény (30) - 11 -

T1.10. Feladat A részlegazonosító szerint csoportosítva listázza azokat a dolgozókat, akiknek fizetése 2000 és 5500 USD közötti érték. A keletkezett lista elsődlegesen a részlegazonosító szerint növekvően, másodlagosan pedig a fizetés szerint csökkenően legyen rendezve. T1.11. Feladat Írassa ki minden jutalékkal rendelkező alkalmazott nevét, jutalékát, főnökének azonosítóját. A lista legyen a főnök azonosítója és az alkalmazottak neve szerint rendezett. #11_SQL Feladatgyűjtemény (30) - 12 -

MEGOLDÁSGYŰJTEMÉNY 1.1. Feladat Írassa ki azon dolgozók munkakörét és fizetését, akiknek fizetése nincs az 1500-2500 USD tartományban. A lista fejléce legyen Név, Munkakör, Fizetés, rendezzen a dolgozók neve szerint. Megoldás SELECT ename AS "Név", job AS "Munkakör", sal AS "Fizetés" WHERE NOT sal BETWEEN 1500 AND 2500 ORDER BY "Név"; Eredmény Név Munkakör Fizetés ---------- --------- ---------- ADAMS CLERK 1100 BLAKE MANAGER 2850 FORD ANALYST 3000 JAMES CLERK 950 JONES MANAGER 2975 KING PRESIDENT 5000 MARTIN SALESMAN 1250 MILLER CLERK 1300 SCOTT ANALYST 3000 SMITH CLERK 800 WARD SALESMAN 1250 11 sor kijelölve. 1.2. Feladat Írassa ki a salesman és a clerk munkakörű azon dolgozók nevét, munkakörét és jövedelmét, akiknek jövedelme nincs az 1500-2500 USD tartományban. A lista fejléce legyen Név, Munkakör, Jövedelem. Megoldás SELECT ename AS "Név", job AS "Munkakör", sal + NVL(comm,0) AS "Jövedelem" WHERE UPPER(job) IN ( SALESMAN, CLERK ) AND NOT sal + NVL(comm,0) BETWEEN 1500 AND 2500 ORDER BY "Név"; Eredmény Név Munkakör Jövedelem ---------- --------- ---------- ADAMS CLERK 1100 JAMES CLERK 950 MARTIN SALESMAN 2650 MILLER CLERK 1300 SMITH CLERK 800 5 sor kijelölve. #11_SQL Feladatgyűjtemény (30) - 13 -

2. Foglalkozás Egytáblás csoportosító lekérdezések Részletesebben lásd [2]: 2. fejezet FELADATGYŰJTEMÉNY 2.1. Feladat Listázza 1981-től éves csoportosításban a dolgozók nevét, munkakörét és jövedelmét a dolgozók neve szerint rendezve. 2.2. Feladat Listázza ki a dolgozók nevét, a belépésük dátumát, valamint azt, hogy a hónap. illetve a hét hányadik napján léptek be (például péntek a hét 5. napja). 2.3. Feladat Listázza 1981-től belépési évenként a legkisebb jövedelmeket. 2.4. Feladat Listázza részlegenként és munkakörönként a legalább 1000 USD-os átlagjövedelmeket. 2.5. Feladat Listázza főnökönként a beosztottak összjövedelmét. 2.6. Feladat Írassa ki az első hat 1000 USD-os fizetésosztályban (0-999, 1000-1999, stb.) dolgozók számát valamilyen célszerű rendezésben. 2.7. Feladat Írassa ki évenként a belépett dolgozók számát. TOVÁBBI FELADATOK T2.8. Feladat Írassa ki munkakörönként a legkisebb és a legnagyobb fizetéseket valamilyen célszerű rendezésben. T2.9. Feladat Írassa ki a hét páros és páratlan sorszámú napjain belépett dolgozók átlagfizetését és átlagjövedelmét, a paritási csoportokban csökkenő átlagjövedelem szerint rendezve. T2.10. Feladat Írassa ki a hónap páros és páratlan sorszámú napjain belépett dolgozók átlagfizetését és átlagjövedelmét, a paritási csoportokban csökkenő átlagjövedelem szerint rendezve. T2.11. Feladat Írassa ki alfabetikus sorrendben az azonos betűvel kezdődő nevű dolgozók számát. #11_SQL Feladatgyűjtemény (30) - 14 -

MEGOLDÁSGYŰJTEMÉNY 2.1. Feladat Listázza 1981-től éves csoportosításban a dolgozók nevét, munkakörét és jövedelmét a dolgozók neve szerint rendezve. 1. Megoldás SELECT TO_NUMBER(TO_CHAR(hiredate,'YYYY')) AS "Belépési év", ename AS "Dolgozó Neve", job AS "Munkaköre", sal + NVL(comm,0) AS "Jövedelem" WHERE TO_NUMBER(TO_CHAR(hiredate,'YYYY')) >= 1981 ORDER BY "Belépési év", "Dolgozó Neve"; Eredmény Belépési év Dolgozó Ne Munkaköre Jövedelem ----------- ---------- --------- ---------- 1981 ALLEN SALESMAN 1900 1981 BLAKE MANAGER 2850 1981 CLARK MANAGER 2450 1981 FORD ANALYST 3000 1981 JAMES CLERK 950 1981 JONES MANAGER 2975 1981 KING PRESIDENT 5000 1981 MARTIN SALESMAN 2650 1981 TURNER SALESMAN 1500 1981 WARD SALESMAN 1750 1982 MILLER CLERK 1300 1987 ADAMS CLERK 1100 1987 SCOTT ANALYST 3000 13 sor kijelölve. Megjegyzés 1. A Smith maradt ki, ő 1980-ban lépett be. 2. Miben fog különbözni a fenti utasítás listája, ha nem alkalmazzuk a TO_NUMBER függvényt? 2. Megoldás (EXTRACT függvénnyel) SELECT EXTRACT(YEAR FROM hiredate) AS "Belépési év", ename AS "Dolgozó Neve", job AS "Munkaköre", sal + NVL(comm,0) AS "Jövedelem" WHERE TO_NUMBER(TO_CHAR(hiredate,'YYYY')) >= 1981 ORDER BY "Belépési év", "Dolgozó Neve"; Eredmény Belépési év Dolgozó Ne Munkaköre Jövedelem ----------- ---------- --------- ---------- 1981 ALLEN SALESMAN 1900 1981 BLAKE MANAGER 2850 1981 CLARK MANAGER 2450 1981 FORD ANALYST 3000 1981 JAMES CLERK 950 1981 JONES MANAGER 2975 1981 KING PRESIDENT 5000 #11_SQL Feladatgyűjtemény (30) - 15 -

1981 MARTIN SALESMAN 2650 1981 TURNER SALESMAN 1500 1981 WARD SALESMAN 1750 1982 MILLER CLERK 1300 1987 ADAMS CLERK 1100 1987 SCOTT ANALYST 3000 13 sor kijelölve. Megjegyzés Az EXTRACT függvény használata Az EXTRACT SQL függvény visszaadja a paraméterében a FROM után megadott dátumkifejezés YEAR, MONTH, DAY, HOUR, MINUTE, illetve SECOND numerikus típusú értékét. Példa SELECT ename AS "Név", hiredate AS "Dátum", EXTRACT(YEAR FROM hiredate) AS "BeÉv", EXTRACT(MONTH FROM hiredate) AS "BeHónap", EXTRACT(DAY FROM hiredate) AS "BeNap" ; Eredmény Név Dátum BeÉv BeHónap BeNap ---------- ---------- ---------- ---------- ---------- SMITH 1980-12-17 1980 12 17 ALLEN 1981-02-20 1981 2 20 WARD 1981-02-22 1981 2 22 JONES 1981-04-02 1981 4 2 MARTIN 1981-09-28 1981 9 28 BLAKE 1981-05-01 1981 5 1 CLARK 1981-06-09 1981 6 9 SCOTT 1987-04-19 1987 4 19 KING 1981-11-17 1981 11 17 TURNER 1981-09-08 1981 9 8 ADAMS 1987-05-23 1987 5 23 JAMES 1981-12-03 1981 12 3 FORD 1981-12-03 1981 12 3 MILLER 1982-01-23 1982 1 23 14 sor kijelölve. 2.2. Feladat Listázza ki a dolgozók nevét, a belépésük dátumát, valamint azt, hogy a hónap. illetve a hét hányadik napján léptek be (például péntek a hét 5. napja). Megoldás SELECT ename AS "DolgozóNév", hiredate AS "Dátum", EXTRACT(DAY FROM hiredate) AS "Nap a hónapban", TO_CHAR(hiredate, DAY ) AS "Nap neve", TO_NUMBER(TO_CHAR(hiredate, D )) AS "Nap a héten" ORDER BY "DolgozóNév"; Eredmény DolgozóNév Dátum Nap a hónapban Nap neve Nap a héten ---------- ---------- -------------- --------- ----------- ADAMS 1987-05-23 23 SZOMBAT 6 ALLEN 1981-02-20 20 PÉNTEK 5 BLAKE 1981-05-01 1 PÉNTEK 5 CLARK 1981-06-09 9 KEDD 2 #11_SQL Feladatgyűjtemény (30) - 16 -

FORD 1981-12-03 3 CSÜTÖRTÖK 4 JAMES 1981-12-03 3 CSÜTÖRTÖK 4 JONES 1981-04-02 2 CSÜTÖRTÖK 4 KING 1981-11-17 17 KEDD 2 MARTIN 1981-09-28 28 HÉTFŐ 1 MILLER 1982-01-23 23 SZOMBAT 6 SCOTT 1987-04-19 19 VASÁRNAP 7 SMITH 1980-12-17 17 SZERDA 3 TURNER 1981-09-08 8 KEDD 2 WARD 1981-02-22 22 VASÁRNAP 7 14 sor kijelölve. 2.3. Feladat Listázza 1981-től belépési évenként a legkisebb jövedelmeket. 1. Megoldás (Előszűréssel) SELECT TO_CHAR(hiredate,'YYYY') AS "Belépés", MIN(sal+NVL(comm,0)) AS "MinJöv" WHERE TO_NUMBER(TO_CHAR(hiredate,'YYYY')) >= 1981 GROUP BY TO_CHAR(hiredate,'YYYY') ORDER BY "Belépés"; Eredmény Belé MinJöv ---- ---------- 1981 950 1982 1300 1987 1100 3 sor kijelölve. Megjegyzés Mi történik, ha a TO_CHAR függvény elé egyik, vagy mindkét helyre betesszük a TO_NUMBER függvényt? 2. Megoldás (Csoportszűréssel) SELECT TO_CHAR(hiredate,'YYYY') AS "Belépés", MIN(sal+NVL(comm,0)) AS "MinJöv" GROUP BY TO_CHAR(hiredate,'YYYY') HAVING TO_NUMBER(TO_CHAR(hiredate,'YYYY')) >= 1981 ORDER BY "Belépés"; Eredmény Belé MinJöv ---- ---------- 1981 950 1982 1300 1987 1100 3 sor kijelölve. Megjegyzés Láthatjuk a két megoldás azonos eredményt adott, de vajon melyik a hatékonyabb? 3. Megoldás (Csoportszűréssel és formázott kiíratással) COLUMN "Belépés" FORMAT A7 SELECT TO_CHAR(hiredate,'YYYY') AS "Belépés", MIN(sal+NVL(comm,0)) AS "MinJöv" #11_SQL Feladatgyűjtemény (30) - 17 -

GROUP BY TO_CHAR(hiredate,'YYYY') HAVING TO_NUMBER(TO_CHAR(hiredate,'YYYY')) >= 1981 ORDER BY "Belépés"; CLEAR COLUMNS Eredmény Belépés MinJöv ------- ---------- 1981 950 1982 1300 1987 1100 3 sor kijelölve. columns törölve Megjegyzés A formázott kiíratásokkal a későbbiekben fogunk részletesebben foglalkozni. 2.4. Feladat Listázza részlegenként és munkakörönként a legalább 1000 USD-os átlagjövedelmeket. Megoldás SELECT deptno AS "Részleg", job AS "Munkakör", AVG(sal + NVL(comm,0)) AS "ÁtlagJövedelem" GROUP BY deptno, job HAVING AVG(sal + NVL(comm,0)) >= 1000 ORDER BY deptno ASC, job ASC, "ÁtlagJövedelem" DESC; Eredmény Részleg Munkakör ÁtlagJövedelem ---------- --------- -------------- 10 CLERK 1300 10 MANAGER 2450 10 PRESIDENT 5000 20 ANALYST 3000 20 MANAGER 2975 30 MANAGER 2850 30 SALESMAN 1950 7 sor kijelölve. 2.5. Feladat Listázza főnökönként a beosztottak összjövedelmét. 1. Megoldás SELECT mgr AS "Főnök", SUM(sal + NVL(comm,0)) AS "ÖsszJövedelem" GROUP BY mgr ORDER BY mgr ASC, "ÖsszJövedelem" DESC; Eredmény Főnök ÖsszJövedelem ---------- ------------- 7566 6000 7698 8750 7782 1300 7788 1100 7839 8275 7902 800 #11_SQL Feladatgyűjtemény (30) - 18 -

5000 7 sor kijelölve. 2. Megoldás (CASE szerkezettel és formázott kiíratással) COLUMN "Főnök" FORMAT A12 SELECT CASE WHEN mgr IS NULL THEN 'Nincs Főnök' ELSE TO_CHAR(mgr) END AS "Főnök", SUM(sal + NVL(comm,0)) AS "ÖsszJövedelem" GROUP BY mgr ORDER BY mgr ASC, "ÖsszJövedelem" DESC; CLEAR COLUMNS Eredmény Főnök ÖsszJövedelem ------------ ------------- 7566 6000 7698 8750 7782 1300 7788 1100 7839 8275 7902 800 Nincs Főnök 5000 7 sor kijelölve. columns törölve 3. Megoldás (Az NVL2 függvénnyel és formázott kiíratással) COLUMN "FőnökKód" FORMAT A12 SELECT NVL2(TO_CHAR(mgr),TO_CHAR(mgr),'Nincs Főnök') AS "FőnökKód", SUM(sal + NVL(comm,0)) AS "ÖsszJövedelem" GROUP BY mgr ORDER BY mgr ASC, "ÖsszJövedelem" DESC; CLEAR COLUMNS Eredmény FőnökKód ÖsszJövedelem ------------ ------------- 7566 6000 7698 8750 7782 1300 7788 1100 7839 8275 7902 800 Nincs Főnök 5000 7 sor kijelölve. columns törölve 2.6. Feladat Írassa ki az első hat 1000 USD-os fizetésosztályban (0-999, 1000-1999, stb.) dolgozók számát valamilyen célszerű rendezésben. Megoldás COLUMN "Fizetés Kategória" FORMAT A17 SELECT CASE WHEN TRUNC(sal/1000) = 0 THEN ' 0-999' WHEN TRUNC(sal/1000) = 1 THEN '1000-1999' WHEN TRUNC(sal/1000) = 2 THEN '2000-2999' #11_SQL Feladatgyűjtemény (30) - 19 -

WHEN TRUNC(sal/1000) = 3 THEN '3000-3999' WHEN TRUNC(sal/1000) = 4 THEN '4000-4999' WHEN TRUNC(sal/1000) = 5 THEN '5000-5999' ELSE 'nincs tovább!' END AS "Fizetés Kategória", COUNT(*) AS "Létszám" GROUP BY TRUNC(sal / 1000) ORDER BY "Fizetés Kategória" DESC; CLEAR COLUMNS Eredmény Fizetés Kategória Létszám ----------------- ---------- 5000-5999 1 3000-3999 2 2000-2999 3 1000-1999 6 0-999 2 5 sor kijelölve. columns törölve Megjegyzés A TRUNC függvény használata szám esetén szintaktika: TRUNC(n [, m]) ahol n, illetve m egész számok megadják az eredményben engedélyezett egész, illetve tizedesjegyek számát. A függvény által visszadott érték egész szám, illetve adott számú tizedesjegyet tartalmazó törtszám típusú. m1. Példa SQL> SELECT TRUNC(600/1000) 2 FROM dual; TRUNC(600/1000) --------------- 0 m2. Példa SQL> SELECT TRUNC(3600/1000) 2 FROM dual; TRUNC(3600/1000) ---------------- 3 m3. Példa SQL> SELECT TRUNC(3600/1000, 1) 2 FROM dual; TRUNC(3600/1000,1) ------------------ 3,6 #11_SQL Feladatgyűjtemény (30) - 20 -

2.7. Feladat Írassa ki évenként a belépett dolgozók számát. 1. Megoldás COLUMN "Belépési év" FORMAT A11 SELECT SUBSTR(TRUNC(hiredate,'YYYY'),1,4) AS "Belépési év", COUNT(*) AS "Létszám" GROUP BY TRUNC(hiredate, 'YYYY') ORDER BY "Belépési év"; CLEAR COLUMNS 2. Megoldás COLUMN "Belépési év" FORMAT A11 SELECT TO_CHAR(hiredate,'YYYY') AS "Belépési év", COUNT(*) AS "Létszám" GROUP BY TO_CHAR(hiredate,'YYYY') ORDER BY "Belépési év"; CLEAR COLUMNS Eredmény Belépési év Létszám ----------- ---------- 1980 1 1981 10 1982 1 1987 2 4 sor kijelölve. columns törölve Megjegyzés A TRUNC függvény használata dátum esetén szintaktika: TRUNC(n, mask) ahol mask a TO_CHAR függvényben használható formátummaszk, és a visszadott érték dátum típusú. m1. Példa SQL> SELECT sysdate, 2 TRUNC(sysdate,'YYYY') 3 FROM dual; SYSDATE TRUNC(SYSD ---------- ---------- 2006-02-19 2006-01-01 m2. Példa SQL> SELECT sysdate, 2 TRUNC(sysdate,'MM') 3 FROM dual; SYSDATE TRUNC(SYSD ---------- ---------- 2006-02-19 2006-02-01 m3. Példa SQL> SELECT emp.*, 2 TRUNC(hiredate,'YYYY') AS "Belépés" 3 #11_SQL Feladatgyűjtemény (30) - 21 -

4 WHERE TRUNC(hiredate,'YYYY') >= 5 TO_DATE('1981-01-01','YYYY-MM-DD'); EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO Belépés ---------- ---------- --------- ---------- ---------- ---------- ---------- ---------- ---------- 7839 KING PRESIDENT 1981-11-17 5000 10 1981-01-01 7698 BLAKE MANAGER 7839 1981-05-01 2850 30 1981-01-01 7782 CLARK MANAGER 7839 1981-06-09 2450 10 1981-01-01 7566 JONES MANAGER 7839 1981-04-02 2975 20 1981-01-01 7654 MARTIN SALESMAN 7698 1981-09-28 1250 1400 30 1981-01-01 7499 ALLEN SALESMAN 7698 1981-02-20 1600 300 30 1981-01-01 7844 TURNER SALESMAN 7698 1981-09-08 1500 0 30 1981-01-01 7900 JAMES CLERK 7698 1981-12-03 950 30 1981-01-01 7521 WARD SALESMAN 7698 1981-02-22 1250 500 30 1981-01-01 7902 FORD ANALYST 7566 1981-12-03 3000 20 1981-01-01 7788 SCOTT ANALYST 7566 1987-04-19 3000 20 1987-01-01 7876 ADAMS CLERK 7788 1987-05-23 1100 20 1987-01-01 7934 MILLER CLERK 7782 1982-01-23 1300 10 1982-01-01 13 sor kijelölve. Megjegyzés az m3.példához A Smith maradt ki, ő 1980-ban lépett be (lásd 2.1. Feladat). #11_SQL Feladatgyűjtemény (30) - 22 -

3. Foglalkozás Többtáblás lekérdezések, allekérdezések Részletesebben lásd [2]: 3. fejezet FELADATGYŰJTEMÉNY 3.1. Feladat Listázza dolgozónként a fizetés és a legnagyobb fizetés közötti különbséget. 3.2. Feladat Listázza 1981-től éves csoportosításban a dolgozók nevét, munkakörét, főnökének nevét és a dolgozó belépési évszámát a dolgozók neve szerint rendezve. (Lásd a 2.1. feladat) 3.3. Feladat Listázza 1981-től belépési évenként a legkisebb fizetésű dolgozók nevét, munkakörét és fizetését a belépés éve szerint csökkenően rendezve. (Lásd a 2.3. feladat) 3.4. Feladat Listázza 1981-től belépési évenként a legnagyobb fizetésű nem-főnök dolgozók adatait, az évek szerint növekvően rendezve. TOVÁBBI FELADATOK T3.5. Feladat Listázza ki munkakörönként a legkisebb fizetésű dolgozók nevét, fizetését, főnökének nevét és főnökének fizetését. T3.6. Feladat Listázza ki a páros és a páratlan sorszámú napokon belépett dolgozók nevét, munkakörét, valamint azt, hogy páros, vagy páratlan napon lépett-e be. T3.7. Feladat Listázza ki növekvő módon rendezve az azonos betűvel kezdődő nevű dolgozók nevét, valamint a nevük mellett megadva azt, hogy csoportjukban hányan vannak. #11_SQL Feladatgyűjtemény (30) - 23 -

MEGOLDÁSGYŰJTEMÉNY 3.1. Feladat Listázza dolgozónként a fizetést, valamint a fizetés és a legnagyobb fizetés közötti különbséget. 1. Megoldás (Allekérdezés a szelekciós listában) SELECT ename AS "Név", sal AS "Fizetés", sal (SELECT MAX(sal) ) AS "Defektus" ORDER BY "Név"; 2. Megoldás (Allekérdezés a FROM utasításrészben In-Line nézet) SELECT ename AS "Név", sal AS "Fizetés", sal x.maxfiz AS "Defektus", (SELECT MAX(sal) AS MaxFiz ) x ORDER BY "Név"; 3. Megoldás (Allekérdezés a WHERE utasításrészben megoldás a MAX függvény nélkül) SELECT a.ename AS "Név", a.sal AS "Fizetés", a.sal b.sal AS "Defektus" a, emp b WHERE b.sal >= ALL (SELECT sal ) ORDER BY "Név"; Eredmény (Mindhárom megoldás esetén) Név Fizetés Defektus ---------- ---------- ---------- ADAMS 1100-3900 ALLEN 1600-3400 BLAKE 2850-2150 CLARK 2450-2550 FORD 3000-2000 JAMES 950-4050 JONES 2975-2025 KING 5000 0 MARTIN 1250-3750 MILLER 1300-3700 SCOTT 3000-2000 SMITH 800-4200 TURNER 1500-3500 WARD 1250-3750 14 sor kijelölve. #11_SQL Feladatgyűjtemény (30) - 24 -

3.2. Feladat Listázza 1981-től éves csoportosításban a dolgozók nevét, munkakörét, főnökének nevét és a dolgozó belépési évszámát a dolgozók neve szerint rendezve. (Lásd a 2.1. feladat) 1. Megoldás SELECT RPAD(d.ename,12) AS "Dolgozó Neve", d.job AS "Munkaköre", RPAD(TO_CHAR(d.hiredate,'YYYY'),12) AS "Belépési éve", RPAD(f.ename,8) AS "Főnöke" d, emp f WHERE d.mgr = f.empno(+) AND TO_NUMBER(TO_CHAR(d.hiredate,'YYYY')) >= 1981 ORDER BY "Belépési éve", "Dolgozó Neve"; Eredmény Dolgozó Neve Munkaköre Belépési éve Főnöke ------------ --------- ------------ -------- ALLEN SALESMAN 1981 BLAKE BLAKE MANAGER 1981 KING CLARK MANAGER 1981 KING FORD ANALYST 1981 JONES JAMES CLERK 1981 BLAKE JONES MANAGER 1981 KING KING PRESIDENT 1981 MARTIN SALESMAN 1981 BLAKE TURNER SALESMAN 1981 BLAKE WARD SALESMAN 1981 BLAKE MILLER CLERK 1982 CLARK ADAMS CLERK 1987 SCOTT SCOTT ANALYST 1987 JONES 13 sor kijelölve. 2. Megoldás (CASE szerkezettel) SELECT RPAD(d.ename,12) AS "Dolgozó Neve", d.job AS "Munkaköre", RPAD(TO_CHAR(d.hiredate,'YYYY'),12) AS "Belépési éve", CASE WHEN f.ename IS NULL THEN 'Nincs Főnöke' ELSE RPAD(f.ename,8) END AS "Főnöke" d, emp f WHERE d.mgr = f.empno(+) AND TO_NUMBER(TO_CHAR(d.hiredate,'YYYY')) >= 1981 ORDER BY "Belépési éve", "Dolgozó Neve"; 3. Megoldás (EXTRACT és NVL2 függvényekkel) SELECT RPAD(d.ename,12) AS "Dolgozó Neve", d.job AS "Munkaköre", RPAD(EXTRACT(YEAR FROM d.hiredate),12) AS "Belépési éve", NVL2(f.ename,f.ename,'Nincs Főnöke') AS "Főnöke" d, emp f WHERE d.mgr = f.empno(+) AND EXTRACT(YEAR FROM d.hiredate) >= 1981 ORDER BY "Belépési éve", "Dolgozó Neve"; Eredmény (2. és 3. megoldás esetén) Dolgozó Neve Munkaköre Belépési éve Főnöke ------------ --------- ------------ ------------ ALLEN SALESMAN 1981 BLAKE BLAKE MANAGER 1981 KING CLARK MANAGER 1981 KING #11_SQL Feladatgyűjtemény (30) - 25 -

FORD ANALYST 1981 JONES JAMES CLERK 1981 BLAKE JONES MANAGER 1981 KING KING PRESIDENT 1981 Nincs Főnöke MARTIN SALESMAN 1981 BLAKE TURNER SALESMAN 1981 BLAKE WARD SALESMAN 1981 BLAKE MILLER CLERK 1982 CLARK ADAMS CLERK 1987 SCOTT SCOTT ANALYST 1987 JONES 13 sor kijelölve. Megjegyzés Az NVL2 függvény használata Az NVL2 SQL függvény az első paraméterének nem-null értéke esetén visszaadja a második paraméterben szereplő kifejezés értékét, míg NULL értéke esetén a harmadik paraméterben szereplő kifejezés értékét. (Lásd a fenti példa.) 3.3. Feladat Listázza 1981-től belépési évenként a legkisebb fizetésű dolgozók nevét, munkakörét és fizetését a belépés éve szerint csökkenően rendezve. (Lásd a 2.3. feladat) 1. Megoldás COLUMN "Belépés" Format A8 SELECT TO_CHAR(hiredate,'YYYY') AS "Belépés", ename AS "Név", job AS "Munkakör", sal AS "MinFiz", (SELECT TO_CHAR(hiredate,'YYYY') AS Belépés, MIN(sal) AS MinFiz WHERE TO_NUMBER(TO_CHAR(hiredate,'YYYY')) >= 1981 GROUP BY TO_CHAR(hiredate,'YYYY')) WHERE TO_CHAR(hiredate,'YYYY') = Belépés AND sal = MinFiz ORDER BY "Belépés" DESC; CLEAR COLUMNS 2. Megoldás (TRUNC függvénnyel, Komáromi Zoltán megoldása) COLUMN "Belépés" Format A8 SELECT TO_CHAR(hiredate,'YYYY') AS "Belépés", ename AS "Név", job AS "Munkakör", sal AS "MinFiz", (SELECT TRUNC(hiredate,'YYYY') AS Belépés, MIN(sal) AS MinFiz WHERE TRUNC(hiredate,'YYYY') >= TO_DATE('1981-01-01','YYYY-MM-DD') GROUP BY TRUNC(hiredate,'YYYY')) WHERE TRUNC(hiredate,'YYYY') = Belépés AND sal = MinFiz ORDER BY "Belépés" DESC; CLEAR COLUMNS 3. Megoldás (Analitikus függvénnyel, Kubatovics Ferenc megoldása) COLUMN "Belépés" Format A8 SELECT TO_CHAR(hiredate,'YYYY') AS "Belépés", ename AS "Név", job AS "Munkakör", #11_SQL Feladatgyűjtemény (30) - 26 -

sal AS "MinFiz" FROM (SELECT emp.*, RANK() OVER (PARTITION BY TO_CHAR(hiredate, 'YYYY') ORDER BY sal) AS Sorszám WHERE hiredate >= TO_DATE('1981-01-01', 'YYYY-MM-DD')) WHERE Sorszám = 1 ORDER BY "Belépés" DESC; CLEAR COLUMNS Eredmény Belépés Név Munkakör MinFiz -------- ---------- --------- ---------- 1987 ADAMS CLERK 1100 1982 MILLER CLERK 1300 1981 JAMES CLERK 950 columns törölve Megjegyzés 1. A fenti megoldások akkor is jól működnének, ha valamelyik évben több legkisebb fizetésű dolgozó is volna. 2. A 3. megoldás olyan eszközt használ, mely nem része az e foglalkozáshoz tartozó tananyagnak (értelmezéséhez lásd [2]: 1.rész, 13.fejezet). 3.4. Feladat Listázza 1981-től belépési évenként a legnagyobb fizetésű nem-főnök dolgozók adatait, az évek szerint növekvően rendezve. 1. Megoldás 1.1. lépés A nem-főnök dolgozók listája (fontos a NULL-érték kezelése): SELECT empno AS azon, ename AS nev WHERE empno NOT IN (SELECT mgr WHERE mgr IS NOT NULL); Másként (egyszerűbben): SELECT empno as azon, ename as nev WHERE empno NOT IN (SELECT NVL(mgr,0) ); Eredmény AZON NEV ---------- ---------- 7844 TURNER 7521 WARD 7654 MARTIN 7499 ALLEN 7934 MILLER 7369 SMITH 7876 ADAMS 7900 JAMES #11_SQL Feladatgyűjtemény (30) - 27 -

8 sor kijelölve. 1.2. lépés A nem-főnök dolgozók legnagyobb évenkénti fizetése az évek szerint növekvően rendezve 1981- től: SELECT MAX(sal) AS MaxFiz, TO_CHAR(hiredate,'YYYY') AS Év WHERE empno NOT IN (SELECT mgr WHERE mgr IS NOT NULL) GROUP BY TO_CHAR(hiredate,'YYYY') HAVING TO_NUMBER(TO_CHAR(hiredate,'YYYY')) >= 1981 ORDER BY Év; Eredmény MAXFIZ ÉV ---------- ---- 1600 1981 1300 1982 1100 1987 Megjegyzés A HAVING utasításrészben azért volt szükség a TO_NUMBER fügvény használatára, mert számokat nem illik karakteresen összehasonlítani! 1.3. lépés Az előző lépésben megkapott adatokhoz illeszkedő dolgozók meghatározása: SET numwidth 5 SELECT *, (SELECT MAX(sal) AS MaxFiz, TO_CHAR(hiredate,'YYYY') AS Év WHERE empno NOT IN (SELECT mgr WHERE mgr IS NOT NULL) GROUP BY TO_CHAR(hiredate,'YYYY') HAVING TO_NUMBER(TO_CHAR(hiredate,'YYYY')) >= 1981) nemfőnök WHERE TO_CHAR(hiredate,'YYYY') = nemfőnök.év AND sal = nemfőnök.maxfiz ORDER BY év; SET numwidth 10 Eredmény EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO MAXFIZ ÉV ----- ---------- --------- ----- ---------- ----- ----- ------ ------ ---- 7499 ALLEN SALESMAN 7698 1981-02-20 1600 300 30 1600 1981 7934 MILLER CLERK 7782 1982-01-23 1300 10 1300 1982 7876 ADAMS CLERK 7788 1987-05-23 1100 20 1100 1987 2. Megoldás (Halmazkivonással) 2.1. lépés A nem-főnök dolgozók listája: SELECT empno MINUS SELECT mgr ; #11_SQL Feladatgyűjtemény (30) - 28 -