Fibonacci-spirál

Fibonacci logó

Fibonacci logóA Fibonacci-spirál a népszerű Fibonacci-sorozat elemei által meghatározott oldalhosszúságú négyzetekbe rajzolt maximális sugarú negyedkörök megfelelően összeillesztett darabjaiból/sorozatából áll. Sokszor hasonlítják az arany spirálhoz (jól közelíti), amely az aranymetszéshez kötődik.

A Fibonacci-spirál

Vegyük a Fibonacci-sorozat első 10 elemét! Rajzoljuk egymás mellé az alábbi elrendezésben belülről kifelé haladva az 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 oldalhosszúságú négyzeteket (az alábbi ábrán vékony sárgával jelölve). Piros színnel rajzoljuk bele a négyzetekbe a négyzet oldalhosszával megegyező sugarú negyedköröket. A negyedkörök megfelelő elrendezésben folytonos görbét alkotnak, és ezt nevezzük Fibonacci-spirálnak (az alábbi ábrán vastag pirossal jelölve).

Fibonacci-spirál 1

A rajzolás bármeddig folytatható, mert a sorozat végtelen, a négyzetek illeszkednek és az ábra rekurzív, önhasonló. Az alábbi animáció mutatja, hogyan alakul a spirál a nézőpont közelítésével. A viselkedés távolítás során is azonos lenne.

Fibonacci-spirál 2

Korábban blogoltunk már a Fibonacci napról, amelyet minden évben november 23-án ünneplünk. A sorozat első néhány eleméből összeáll a 11.23. és értelmezhető dátumként. Most nem a sorozat elemeinek előállítására fókuszálunk, hanem arra, hogy ezekből felépítsük a Fibonacci-spirált.

Készítsünk Java programot!

Grafikus felületű Java programot készítünk, amely 21 animációs fázisban mutatja be a Fibonacci-sorozat első 10 eleméből álló Fibonacci-spirál felépítését. A rajzolás fázisai:

  • Az 1. fázis a kiindulópontként tekinthető fehér, üres rajzlap. A rajzlap fekvő, mérete 890*550 pixel, amelyre éppen elfér a 10 negyedkörből álló spirál.
  • A 2-11. fázisban megfelelő pozícióba/koordinátákra kerülnek fel az ábra vázát alkotó négyzetek, belülről kifelé haladva. A négyzetek oldalainak hosszúsága a sorozat elemeinek megfelelő. A szomszédos négyzetek különböző színekkel kitöltöttek és mindegyikben megjelenik a sorozat megfelelő eleme.
  • A 12-21. fázisban – szintén belülről kifelé haladva – a négyzetek törlődnek és helyükre a spirált alkotó negyedkörök kerülnek fekete színnel. A 21. fázist tekintjük végeredménynek.

A fázisok kézzel, nyilakkal jelölt (Első, Előző, Következő, Utolsó) vezérlő nyomógombokkal megjeleníthetők, illetve egyben, időzítve animációként is lejátszható a rajzolási folyamat. Az elkészült program működése megfigyelhető az ábrán:

Fibonacci-spirál Java program

A bejegyzéshez tartozó teljes forráskódot ILIAS e-learning tananyagban tesszük elérhetővé tanfolyamaink résztvevői számára.

A Java SE szoftverfejlesztő tanfolyamunkon, a szakmai modul Objektumorientált programozás témakörét követő 29-36. óra Grafikus felhasználói felület alkalmain már tudunk egyszerűbb szimulációs programot tervezni, kódolni, tesztelni.

Népesedési világnap

Népesedési világnap logó

Népesedési világnap logóAz ENSZ 1987-ben július 11-ét a népesedési világnappá (World Population Day) nyilvánította. Bolygónk lakossága aznap érte el az 5 milliárdot. További kerek számok voltak: 1999. október 12-én 6 milliárd, 2011. október 30-án 7 milliárd. További kerek számok várhatóak: 2023 – 8 milliárd, 2037 – 9 milliárd, 2057 – 10 milliárd. A KSH elemzése részletes elemzéseket közöl évről-évre a témában, például: 2019-ben, 2018-ban. A worldometer.info weboldalon folyamatosan frissülő kimutatások érhetők el a népességhez globálisan, valamint országonként is: például Magyarország aktuális népesedési adatai.

A népesedési világnap inspirált egy Java program megtervezésére és megírására. A swing GUI-s program megjeleníti a worldometer.info weboldalról kinyerhető adatok alapján régiónként (kontinensenként) az elérhető adatokat 1950-től 2020-ig az alábbiak szerint egy világtérképen.

Az elkészült program

Népesedési világnap Java program

Tervezés

Objektumorientált szemlélettel, MVC architekturális tervezési mintát követünk, angol nyelvű interfész, osztály, változó, objektum, metódus nevekkel. A projekt neve: WorldPopulation, a csomag neve: worldpopulation. Amit lehet, konstansként interfészbe (szeparálva) teszünk és az MVC rétegekhez kötődő osztályok implementálják. A modell minden évszámhoz tárolja a szükséges adatokat, mindezt egyetlen betöltéssel/letöltéssel éri el. A program kliensként hat régióra vonatkozó adatot gyűjt össze, alkalmazkodva a szerver adatforráshoz. A címsorban lévő összesített adat is elérhető közvetlenül a weboldalon, de a kisebb adatforgalom érdekében hasznos inkább a kliensben összesíteni. Mindössze egyetlen eseménykezelés szükséges: a csúszka beállításával megadott évszám alapján frissíteni kell a régiók címkéit és az ablak címsorát. Öröklődés hasznos a feladat megoldása során: egyrészt interfészek, másrészt osztályok között.

Interfészek

Az ősinterfész a WorldPopulationConstants, benne az évszám intervallum MIN_YEAR és MAX_YEAR határaival, valamint a megjeleníthető régiók neveivel tömbben: REGION_NAME_ARRAY. Két utódinterfész épül az ősre: ModelConstants és ViewConstants. Előbbi interfész az adatforráshoz kapcsolódik: URL_COMMON az URL eleje, URL_ARRAY az URL végei régiónként tömbben. Utóbbi interfész a megjelenítéshez kapcsolódik: WORLD_MAP_IMAGE a háttérkép annak WORLD_MAP_RECT méretével együtt, valamint a régiónkénti REGION_RECT_ARRAY téglalapok tömbje a kezdeti pozíciókkal/méretekkel, TITLE a sablon a program címsorához (frissítendő az évszámmal és az összesített népességgel). A megfelelő utódinterfészt mindig implementálja az MVC szerint hozzá illeszkedő osztály.

Osztályok

A belépési pont a WorldPopulation.java fájlban található.

Három összetartozó elemi adatot fog össze egybe a RegionData POJO, ezek name, year, population nevű rendre String, int, long típusú adatok. Például: Európa, 2020, 747643253. Tartalmaz két függvényt: getPopulation(), valamint toString(). Utóbbi HTML formátumban adja vissza a megjelenítendő adatokat.

A JLabel-ből származik az igényekhez alakított RegionLabel osztály. Ennek van előre megadott pozíciója, mérete, betűtípusa, betűmérete, sárga háttérszíne, piros kerete. Ezenkívül a téglalap átlátszó, valamint a benne megjelenő HTML tartalom vízszintesen középre igazított. Némi extra funkció, hogy egérrel megfogva – drag and drop – áthelyezhető, ami a MouseMotionListener egérmozgást figyelő interfész mouseDragged() metódusának felülírásával válik lehetővé. A mozgathatóságáért saját maga felel. Példaként közöljük az osztály teljes forráskódját:

A webről adatokat szerez és tárolja a Model osztály, a java.io és java.net csomagokra építve. Egy példa: a https://www.worldometers.info/world-population/europe-population/ oldal forrásából nyeri ki az osztály az alábbi adatokat:

Ezek parszolását követően elkészül egy optimálisnak tekinthető, generikus listákból álló regionListArray tömb adatszerkezet. A parszolás történhet egyszerű szövegkezeléssel vagy JSON feldolgozással is. Erre épülnek a konstruktorral és vezérlővel összehangoltan működő getter metódusok: getHTML(), getRegionList(), getRegionData(), getPopulation(). A JSON adatforrás feldolgozását most nem részletezzük, de hasonlóról blogoltunk már: Időjárás Budapesten.

A grafikus felhasználói felületet adja a JFrame utód View osztály. Három GUI komponensből áll: pnWorldMap – háttérkép JPanel, lbYear – kiválasztott/aktuális év JLabel, slYear – kiválasztható/görgethető aktuális év JSlider. Izgalmas megoldani egymásra/egymáson elhelyezni a komponenseket. Egy JLayeredPane komponens  DEFAULT_LAYER rétegére kerül a térképet tartalmazó háttérkép, majd a  PALETTE_LAYER rétegére kerül dinamikusan a hat  RegionLabel osztályú/típusú objektum. A csúszka komponens slYearStateChanged() eseménykezelő metódusa vezérlőként megszólítja a modell réteget és a visszakapott adatokkal frissíti a nézet réteget (a címsorban lévő összesítéssel együtt, ezres szeparátorokkal).

Ötlet továbbfejlesztésre

Hat különböző weboldal forráskódjából kell összegyűjteni a megjelenítendő adatokat. Ez 2020-ban régiónként 71 számot jelent és hat régió van. Érdemes lehet olyan adattárolást megvalósítani, amely csökkenti a szerverhez fordulások számát, illetve a letöltendő adatok mennyiségét. Hiszen a múltbeli évekhez kötődő historikus adatok nem változnak. Ha ezekre valamilyen formában a program emlékszik, akkor elegendő az utolsó tárolt évből kiindulva az aktuális évig évenként, régiónként lekérni mindössze 6, 12, 18… számot, a program utolsó futtatásának évéből kiindulva. Ez lényegesen kevesebb lenne, mint a jelenlegi 6*71 lekért szám. A koncepció kulcsszava: inkrementális adatfrissítés. Ha megvalósítjuk az ötletet, akkor figyelni kell arra, hogy az aktuális/utolsó évben az adatok akár másodpercenként is változhatnak.

A bejegyzéshez tartozó teljes forráskódot ILIAS e-learning tananyagban tesszük elérhetővé tanfolyamaink résztvevői számára.

A feladat a Java SE szoftverfejlesztő tanfolyam tematikájához kötődik (ha a swing GUI-ra koncentrálunk és az adatok helyi fájlrendszerből elérhetők), és a Java EE szoftverfejlesztő tanfolyam tematikájához kapcsolódik (ha az adatokat közvetlenül a webről olvassuk).

Multimédia az oktatásban 2020

NJSZT-MMO logó

NJSZT-MMO logóA Neumann János Számítógép-tudományi Társaság (NJSZT) „Multimédia az oktatásban” Szakosztály által – évente – szervezett XXVI. Multimédia az oktatásban című online nemzetközi konferencia került megrendezésre 2020. június 11-12-én. Az online platformot a Pexip webkonferencia szolgáltatás biztosította.

A konferencia célja

A szakmai rendezvény célja, hogy elősegítse az oktatás, valamint a kutatás és fejlesztés különböző területein dolgozó, oktató hazai és külföldi szakemberek, PhD és felsőoktatási hallgatók kapcsolatfelvételét, tapasztalatok és jó gyakorlatok cseréjét, egyes képzési szakterületekhez kapcsolódó kreditek gyűjtését.

24 témakörben hirdették meg az előadóknak a jelentkezési lehetőséget, köztük néhány hozzánk kötődő

  • élethelyzethez igazított tanulás,
  • a multimédia alkalmazása a felsőoktatásban és a felnőttképzésben,
  • mLearning, eLearning és környezete,
  • a tanulási környezet technikai, technológiai változása,
  • felhőalapú szolgáltatások,
  • multimédia és a tudományos kutatás összefonódása,
  • multimédia-fejlesztések, eredmények, alkalmazások bemutatása.

Letölthető a konferencia absztrakt kötete, benne a konferencia programjával.

Részt vettem a konferencián

Már többször is részt vettem előadóként ezen a konferencián szakmai előadással, magyar és/vagy angol nyelvű cikkel, poszterrel az oktatói csapat tagjaival együtt. Ezek a publikációs listámban megtalálhatók. Legutóbb tavaly, lásd Multimédia az oktatásban 2019.

2020-ban előadást tartottam „Analysis of the Sorting with distribution and counting algorithm; is it worth or not?” (Szétosztva leszámoló rendezési algoritmus hatékonyságának vizsgálata, jobb vagy sem?) címmel 20 percben, amely a konferencia „Multimédia-fejlesztések, eredmények, alkalmazások bemutatása/ Az űrkutatás és űrtevékenység a modern oktatásban” című szekciójába került. Előadásom rövid, angol nyelvű összefoglalója az absztrakt kötet 19-20. oldalán olvasható. Előadásom prezentációját ILIAS e-learning tananyagban tesszük elérhetővé tanfolyamaink résztvevői számára.

Előadásom témája a Java SE szoftverfejlesztő tanfolyam 5-8. óra: Vezérlési szerkezetek, 9-12. óra: Metódusok, rekurzió, 13-16. óra: Tömbök alkalmaihoz kapcsolódik.

Multimédia az oktatásban online nemzetközi konferencia 2020

A teljes konferencia élő közvetítésben zajlott a Dunaújvárosi Egyetemről. 2 nap alatt 51 előadás hangzott el. 5 országból 300 fő követte. Egy-egy szekciót átlagosan 50 fő látogatott. A plenáris előadások a mesterséges intelligencia témakörhöz kapcsolódtak. Külön kiemelném Gulyás István kiváló összefoglalóját a 4 ipari forradalomról. A program szerteágazó, színvonalas és izgalmas volt. Az aktuális digitális oktatás technológiai és módszertani kihívásaival több előadás is foglalkozott. Számomra hasznosnak bizonyult az ezekhez kötődő többféle nézőpontból való megközelítés. A szakmai társalgás virtuális konferenciaszobákban folyt, és a szervezők még további 3 beszélgetős sarkot is létrehoztak a kötetlen kommunikáció biztosítására. A szervezés abszolút profi volt, a korábbi évek offline eseményeihez hasonlóan. Jövőre is szívesen csatlakozom a rendezvényhez. 2021-ben a Multimédia az oktatásban konferencia helyszíne a Dunaújvárosi Egyetem lesz.

Céline Dion – Courage World Tour

Céline Dion Courage World Tour

Céline Dion Courage World TourA Céline Dion – Courage World Tour esettanulmányunkban a turné első részének koncerthelyszíneit jelenítjük meg Google Charts segítségével. Ebben a blog bejegyzésben a tervezés, megvalósítás lépéseit tekintjük át és megmutatjuk az eredményeket. A Java és JavaScript forráskódokat most nem részletezzük.

Háromféle grafikont használunk

  • idővonal (Timeline) időpontok és helyszínek Gantt diagram-szerűen,
  • térkép (Geo Chart) városok megjelölésével és időpontok jelmagyarázatban,
  • tematikus térkép az USA államaival (szintén Geo Chart), az állam területén adott koncertek száma alapján és db jelmagyarázatban.

A tervezés és megvalósítás lépései

  1. Adatokat kell szerezni egy weboldal (https://www.celinedion.com/in-concert/) feldolgozásával ( saveHTML()). Ehhez a művelet a GET. Figyelni kell a megfelelő User-Agent paraméterezésére és a karakterkódolásra ( ISO-8859-1). A kapott bemeneti folyam feldolgozását pufferelt módon érdemes elvégezni. Célszerű az adatforgalom minimalizásása érdekében a weboldal tartalmát helyi fájlba menteni ( tour.html). Ügyelni kell a kötelező és az ajánlott kivételkezelésre.
  2. Értelmezni kell a tour.html fájlt. A HTML tartalom végén JSON formátumban beágyazva elérhetők a koncert turné állomásainak adatai: nekünk kell a város ( city), helyszín ( venue), dátum/idő ( startDate). Érdemes külön fájlba menteni a tour.html-ből a JSON tartalmat ( tour.json), mert abból egyszerűen betölthető ( saveJSON()).
  3. Tanulmányozni kell a Google Charts diagramok közül azt a kettőt, amiket testre kell szabni: Timeline és Geo Chart. Tudni kell: mi a diagramot tartalmazó weboldal állandónak tekinthető eleje és vége (ezeket hasznos külön interfészben konstansként tárolni: HTMLFileContent), valamint mi az adatoktól függő része (közepe). Ismerni kell a szükséges metaadatok és adatok formátumát. Érdemes átnézni a különböző testre szabási és formázási lehetőségeket a fenti diagramtípusoknál (esetleg a többi típusból is meríthetünk ötleteket).
  4. A koncert turné állomásainak összetartozó 3 adatát le kell képezni POJO-vá ( Event). Ezt érdemes privát változókkal ( city, venue, startDate) és factory metódussal megvalósítani. Célszerű, ha az adatok visszakérésére alkalmas getter metódusok is készülnek ( getTimelineChartDataTableRow(), getGeoChartDataTableRow()), amelyek kiszolgálják a megfelelő diagramtípus igényeit.
  5. A tour.json fájl feldolgozásával (parszolásával) Event típusú generikus listába vagy JSON tömbbe könnyen leképezhetők az adatok.
  6. Hasznos egy vezérlőosztály létrehozása, amely a 3 diagramtípust előállító (HTML fájlt generáló) metódust ( createTimelineChart(), createGeoChartCity(), createGeoChartCountry()) valamint a belépési pontot ( main()) tartalmazza.
  7. Generálható az idővonalat tartalmazó timelineChart.html fájl a createTimelineChart()metódussal. Ehhez 5 oszlop megadása szükséges (ebben a sorrendben): label, city, tooltip, start, end. Az első 3 adat string, az utolsó 2 adat date típusú. Egy példa Event: ['2019.09.18.', 'Québec, QC', 'Videotron Centre', new Date(2019, 09, 18, 19, 0, 0), new Date(2019, 09, 18, 21, 0, 0)].
  8. Regisztrálni kell egy Google Cloud Platform felhasználói fiókot és tanulmányozni kell a geokódolás folyamatát és lehetőségeit, hiszen a városok nevéből (formátum pl.: 'Minneapolis, MN') szükség lesz azok térképi koordinátáira. Aktiválni kell a szolgáltatás használatához szükséges mapsApiKey-t.
  9. Generálható a városokat tartalmazó geoChartCity.html fájl a createGeoChartCity() metódussal. Ehhez 3 oszlop megadása szükséges (ebben a sorrendben): city, dateCity, no . Egy példa Event: ['Minneapolis, MN', '2019.11.01. Minneapolis, MN', 1].
  10. Generálható a régiókat/államokat tartalmazó geoChartCountry.html fájl a createGeoChartCountry() metódussal. Ez egy tematikus térkép: a különböző színek jelölik az egy régió/állam városaiban tartott koncertek számát. Ehhez az adatok megfelelő rendezését követően végrehajtott csoportváltás algoritmus szükséges. 2 oszlop megadása szükséges: country, concertNo. Egy példa adatsor: ['US-TX', 3].

Az eredmények

TimelineChart grafikon:

GeoChartCity grafikon:

GeoChartCountry grafikon:

Érdemes megismerni további – térképekhez kapcsolódó – grafikontípusokat is: Geomap, Intensity Map.

A bejegyzéshez tartozó teljes forráskódot ILIAS e-learning tananyagban tesszük elérhetővé tanfolyamaink résztvevői számára.

A példák a Java SE szoftverfejlesztő tanfolyam 37-44. óra: Fájlkezelés és a Java EE szoftverfejlesztő tanfolyam 1-4. óra: Elosztott alkalmazások, webszolgáltatások és 13-16. óra: JSON feldolgozás alkalmaihoz kötődnek.

Top 5 fizetésű alkalmazottak listája

Top5 fizetés

Top5 fizetésAz a fela­da­tunk, hogy az Oracle HR sé­má­ból le­kér­dez­ve állít­suk elő a top 5 fizetésű alkalmazottak listáját, a fizetések csökkenő sorrendjében. Ez egytáblás lekérdezéssel megvalósítható. Az EMPLOYEES táb­lában megtalálható az összefűzött névhez szükséges FIRST_NAME és LAST_NAME mezők, valamint a fizetés a SALARY mezőben. Min­den alkalmazottnak van neve és fizetése. Előfordul legalább 5 különböző fizetés.

Oracle HR séma

Tanfolyamainkon többféleképpen modellezzük és tervezzük meg a feladat megoldását.

Megoldás (Java SE szoftverfejlesztő tanfolyam)

A Java SE szoftverfejlesztő tanfolyam 45-52. óra: Adatbázis-kezelés JDBC alapon alkalmain a következők szerint modellezünk és tervezünk.

Kiindulunk az alábbi egyszerű lekérdező parancsból (V1):

Top5SalaryV1Select

Eredményül ezt kapjuk (részlet, V1):

Top5SalaryV1 Eredmény

A kapott 107 rekordból álló eredménytáblát a Java kliensprogram fejlesztése során leképezzük egy generikus POJO listába, a rekordonként összetartozó két adatból előállítva az objektumok tulajdonságait. Kiderül, hogy a 17000 többször is előfordul. Mivel bármely fizetés előfordulhatna többször is, így előre nem tudjuk, hogy az eredménytáblából mennyi rekordot kell áttölteni a listába. A fizetésekből generikus halmazt építhetve, addig tudjuk folytatni a beolvasást, amíg a halmaz elemszáma kisebb ötnél. Eredményül hat rekordot kapunk. A Java kliensprogram forráskódját most nem részletezzük, de tanfolyamaink hallgatói számára ILIAS e-learning tananyagban tesszük elérhetővé a teljes forráskódot. Ennél a megoldásnál egyszerűbb a lekérdező parancs, de több feladat hárul a Java kliensprogramra.

Lássunk néhány tévutat és az általános megoldás helyett konkrét megoldásokat! Ha szeretnénk adatbázis oldalon megoldani a feladatot, akkor használhatnánk a ROWNUM pszeudooszlopot. Ez 1-től sorszámozza az eredménytáblát, így használható lehetne arra, ha limitálni szeretnénk a visszaadandó rekordok számát.

1. elvi hibás lekérdező parancs:

Top5SalaryV2 Select

1. elvi hibás eredmény:

Top5SalaryV2 Eredmény

A hiba elvi, a lekérdező parancs szintaktikailag helyes. A harmadik oszlopban látjuk, hogy a rekordok sorszámozása megtörténik, de a kapott nevek és fizetések eltérnek a V1 esetben kapott helyes eredménytől. Az okokat természetesen megbeszéljük. Támpont: próbáljuk meg a lekérdező parancs feltételében kicserélni az 5-öt például 10-re és próbáljuk megmagyarázni, miért kapjuk azt, amit kapunk. Továbbá a konkrét esetben tudjuk, hogy hat rekordot kellene kapunk. Felmerülhet a gyanú, hogy a rendezés túl későn történik meg. Megpróbáljuk zárójelezéssel és lekérdezések egymásba ágyazásával befolyásolni a WHERE és ORDER BY alparancsok végrehajtási sorrendjét.

2. elvi hibás lekérdező parancs:

Top5SalaryV3 Select

2. elvi hibás eredmény:

Top5SalaryV3 Eredmény

A hiba most is elvi, a lekérdező parancs szintaktikailag helyes. A zárójelezés valóban hatással van a két alparancs végrehajtási sorrendjére és megfigyelhető, hogy a harmadik oszlopban a rekordok táblabeli fizikai sorrendje jelenik meg és a feltétel ( ROWNUM <= 5) nem a mező értékére, hanem a rekordok darabszámára értendő. Nyilván az 5-öt 6-ra módosítva visszakaphatnánk a V1 első hat rekordját, de ez nem lenne általános megoldás. Más úton is eljuthatunk a konkrét megoldáshoz.

3. elvi hibás lekérdező parancs:

Top5SalaryV4 Select

3. konkrét megközelítéssel kapott helyesnek látszó eredmény:

Top5SalaryV4 Eredmény

A hiba most is elvi, a lekérdező parancs szintaktikailag helyes. Általános megoldás helyett konkrét megoldásként megkapjuk a V1 első hat rekordját, de ehhez be kellett építeni a lekérdező parancsba a 13000-et. Ez a Top 5-ben legkisebb fizetés. Megbeszéljük, hogy miért hasznos a DISTINCT módosító/kulcsszó beépítése a lekérdező parancsba.

Megoldás (Java adatbázis-kezelő tanfolyam)

A Java adatbázis-kezelő tanfolyam 9-12. óra: Oracle HR séma elemzése, 13-16. óra: Konzolos kliensalkalmazás fejlesztése JDBC alapon, 1. rész, 33-36. óra: Grafikus kliensalkalmazás fejlesztése JDBC alapon, 2. rész alkalmával a következők szerint modellezünk és tervezünk.

Most arra helyezzük a hangsúlyt, hogy back-end, azaz adatbázis oldalon állítsuk elő az eredményt és ezáltal a front-end, azaz a Java kliensprogram egyszerűbb lehet. A lekérdező parancsot belülről kifelé haladva gondoljuk végig. Először kell egy halmaz a különböző fizetésekről csökkenő sorrendben. Utána ebből kell az első öt darab, amelyek halmazt alkotnak. Végül erre építve kell azoknak az alkalmazottaknak a neve és fizetése, akiknek a fizetése benne van a halmazban.

1. majdnem helyes megoldás:

Top5SalaryV5 Select

1. általános megközelítéssel kapott helyesnek látszó eredmény:

Top5SalaryV4 Eredmény

A probléma az, hogy az adatok helyes sorrendje a véletlennek köszönhető. Ha a lekérdező parancs feltételében az 5 helyett nagyobb számokat helyettesítünk be, akkor ez jól megfigyelhető. A következő megoldás már ezt a problémát is kezeli.

Finomítva a 3. elvi hibás lekérdező parancsot, a konkrét 13000 helyettesíthető belső lekérdező paranccsal. Építsük ezt be az 1. helyes megoldásba úgy, hogy az IN predikátum helyett használjuk a nagyobb vagy egyenlő hasonlító operátort. A középső lekérdező parancs a halmaz helyett már csak egyetlen értéket adjon vissza, amelyhez könnyű hasonlítani az aktuális alkalmazott fizetését. Ezzel kiváltható a nagyobb memóriaigényű halmazban való tartalmazottságot eldöntő művelet, a jóval hatékonyabb egy értékkel való összehasonlítással. Memóriaigény szempontjából nem maga a konkrét művelet/operátor az érdekes, hanem a használatukhoz szükséges adatok előállítása, mennyisége, tárolása, feldolgozása.

2. helyes megoldás:

Top5SalaryV6 Select

2. általános megközelítéssel kapott helyes eredmény:

Top5SalaryV4 Eredmény

Közben az is kiderült, hogy miért szükséges két helyen az ORDER BY alparancs.

Végül, ha ismerjük az Oracle DENSE_RANK() analitikai függvényét, amely egy rendezett lista különböző elemeihez rendel sorrendben számokat (másképpen rangsort állít fel 1-től kezdve), akkor elkészíthetjük az alábbi megoldást.

3. helyes megoldás:

Top5SalaryV7 Select

3. általános megközelítéssel kapott helyes eredmény:

Top5SalaryV7 Eredmény

Érdemes átgondolni és összehasonlítani a többféle különböző megközelítés lehetőségeit, korlátait. Ha egyensúlyozni kell a kliensprogram és az adatbázis-szerver terhelése között, valamint az MVC modell összetettsége, karbantarthatósága, könnyen dokumentálhatósága a/is szempont, akkor többféle alternatív módszer is bevethető, valamint építhetünk a különböző Oracle verziók (dialektusok) képességeire is.

Az SQL forráskódok formázásához a Free Online SQL Formatter-t használtam.