Sapientia - Erdélyi Magyar TudományEgyetem (EMTE ) Marosvásárhely

Preview:

DESCRIPTION

Sapientia - Erdélyi Magyar TudományEgyetem (EMTE ) Marosvásárhely. ABR ( Adatb á zisrendszerek ) 12. El ő ad á s: 0. Egyes érdekesebb lek érdezésekről NULL értékek használata alkérdésekben Sz ámlanyilvántartási feladat megoldása Illyés László. - PowerPoint PPT Presentation

Citation preview

1

Sapientia - Erdélyi Magyar TudományEgyetem (EMTE) Marosvásárhely

ABR ( Adatbázisrendszerek)

12. Előadás:

0. Egyes érdekesebb lekérdezésekről 1. NULL értékek használata alkérdésekben2. Számlanyilvántartási feladat megoldása

Illyés László

Sapientia - Erdélyi Magyar TudományEgyetem (EMTE) Csíkszereda

b) Keressük meg a legdrágább nyomtatókat?c) Keressük meg azokat a laptopokat, amelyek minden PC-nél lassúbbak?d) Keressük meg a modellszámát a legdrágább terméknek (PC, laptop

vagy nyomtató)

SELECT modell FROM NyomtatoWHERE ar=(SELECT MAX(ar) FROM Nyomtato);

SELECT modell FROM LaptopWHERE sebesseg< ALL (SELECT sebesseg FROM PC);

Q1=(SELECT modell,ar FROM PC) UNION (SELECT modell,ar FROM Laptop) UNION (SELECT modell,ar FROM Nyomtato);

SELECT modell FROM Q1 WHERE ar=(SELECT MAX(ar) FROM Q1)2

Sapientia - Erdélyi Magyar TudományEgyetem (EMTE) Csíkszereda

e) Keressük meg a legolcsóbb színes nyomtatók gyártóit?

SELECT gyarto FROM Termek WHERE modell IN(SELECT modell FROM Nyomtato WHERE szines ANDar=(SELECT MIN(ar) FROM Nyomtato));

SELECT gyarto FROM Termek WHERE modell IN(SELECT modell FROM Nyomtato WHERE ar=(SELECT MIN(ar) FROM Nyomtato WHERE szines));

Három variáns

Melyik a jó

És miért

e1

e2

e3 SELECT gyarto FROM Termek WHERE modell IN(SELECT modell FROM Nyomtato WHERE szines AND ar=(SELECT MIN(ar) FROM Nyomtato WHERE szines));

3

Sapientia - Erdélyi Magyar TudományEgyetem (EMTE) Csíkszereda

f) Keressük meg annak a PC-nek a gyártóját, amely a leggyorsabb processzorú PC-t gyártja a legkisebb memóriájú PC-k között.

Q2=SELECT gyarto, sebesseg FROM Termek INNER JOIN PC ON Termek.modell=PC.modell WHERE sebesseg IN (SELECT sebesseg FROM PC WHERE memoria=(SELECT MIN(memoria) FROM PC));

SELECT gyarto FROM Q2 WHERE sebesseg =(SELECT MAX(sebesseg) FROM Q2)

4

Sapientia - Erdélyi Magyar TudományEgyetem (EMTE) Csíkszereda

d) Keressük meg a “D” gyártó által gyártott PC-k és laptopok átlagos árát?e) Keressük meg minden egyes PC-sebességéhez az ilyen sebességű PC-k átlagos árát?f) Keressük meg minden gyártó esetén a laptopok átlagos képernyőméretét?

d)Q1=(SELECT ar FROM Termek INNER JOIN PC ON Termek.modell=PC.modell WHERE Termek.gyarto=‘D’) UNION ALL (SELECT ar FROM Termek INNER JOIN Laptop ON Termek.modell=Laptop.modell WHERE Termek.gyarto=‘D’);SELECT AVG(ar) FROM Q1;

e) SELECT sebesseg, AVG(ar) FROM PC GROUP BY (sebesseg);

f) SELECT gyarto, AVG(kepernyo) FROM Termek INNER JOIN laptop ON Termek.modell=laptop.modell GROUP BY (gyarto);

5

6

CREATE TABLE table1(KOD INTEGER PRIMARY KEY, ertek INTEGER);CREATE TABLE table2(KOD INTEGER PRIMARY KEY, ertek INTEGER);INSERT INTO table1 VALUES (1,1),(2,2);INSERT INTO table2 VALUES (1,1),(2,2),(3,3),(4,4),(5,5);SELECT ertek FROM table2 WHERE ertek NOT IN (SELECT ertek FROM table1);Eredmény: 3,4,5INSERT INTO table1 VALUES (6,null); Eredmény: NULL ugyanazzal a lekérdezésselEgy megoldás:SELECT ertek FROM table2 WHERE ertek NOT IN (SELECT ertek FROM table1 WHERE ertek IS NOT null);

NULL érték használata alkérdésekben (Celko J., SQL felsőfokon, Kiskapu, 117-119)

7

Az IN predikátumot a következő képpen határozzuk meg:SELECT ertek FROM table2 WHERE NOT (ertek= ANY(SELECT ertek FROM table1));

Ebből következik, hogy:SELECT ertek FROM table2 WHERE NOT((ertek=1) OR (ertek=2) OR (ertek=3) OR (ertek=4) OR (ertek=5) OR (ertek=NULL));

DeMorgan azonosságokat alkalmazvaSELECT ertek FROM table2 WHERE((ertek<>1) AND (ertek<>2) AND (ertek<>3) AND (ertek<>4) AND (ertek<>5) AND UNKNOWN)

Eredmény mindíg UNKNOWN lesz, ami a WHERE záradékban nem lehet.

8

NULL érték kiküszöbölése a gyakorlatban

0 ismeretlen1 férfi2 nő9 N/A

Filmek

hossz

fegyver

cím év szalagFajta

azegy

azegyazegy

azegy

Rajzfilmek Bűnűgyi filmek

Hangok

Bűnűgyi Rajzfilmek

szerep

9

Film(cím, év, hossz, szalagfajta)

BűnűgyiFilm(cím, év, hossz, szalagfajta, fegyver)

Rajzfilm(cím, év, hossz, szalagfajta)

Hang(filmCím, gyártÉv, színészNév, szerep)

BűnűgyiRajzfilm(cím, év, hossz, szalagfajta, fegyver)

Egyedhalmazok összevonása nullérték használatával

Film(cím, év, hossz, szalagfajta, fegyver, hang)

Hang(filmCím, gyártÉv, színészNév, szerep)

10

Sapientia - Erdélyi Magyar Tudományegyetem (EMTE) Marosvásárhely

Egy lehetséges megkülönböztetés NULL érték használatával

Hang Fegyver Filmtipús

NULL -1 NULL “” Film

NULL -1 Érték Bűnűgyi film

0 0 NULL “” Néma rajzfilm

0 0 Érték Néma bűnűgyi rajzfilm

1 1 NULL “” Hangos rajzfilm

1 1 Érték Hangos bűnűgyi rajzfilm11

12

Feladat:

Egy cégnél adatbázisban szeretnénk tárolni a kimenő és bejövő

számlák információit. Szeretnénk tudni, hogy mindenik számlán

milyen terméket adtunk el, hogy a kimenő számlák melyik cégnek

voltak kibocsájtva, a cégek milyen kifizetéseket eszközöltek ezen

számlákra és hogy mennyivel tartoznak, vagy késésben vannak-e a

megadott határidő szerint. A határidő a számlához tartozik, nem a

céghez. Ugyanakkor nyilvántartjuk a bejövő számláinkat is, de csak

összeg szerint és a saját kifizetéseink szerint. Az ügyfeleink, a

beszállítók és a vevők egy táblában tárolódnak. A mi kifizetéseinket

is nyilvántartjuk. Egy számlára történhetnek részleges kifizetések is.

13

Zölddel írva a számla általános adatait láthatjuk

Pirossal a számlasorok attribútumai vannak

Kékkel írva láthatóak a számlasorok.

14

Sapientia - Erdélyi Magyar TudományEgyetem (EMTE) Marosvásárhely

Ügyfelek

számlaszám

termékID

Számlák

számlája

sorai

mennyiség

SorszámÁFA

Számlasorok

mértékegység

egységár

Termékek

Dátum

terméke

név

határidő

azonosító

név bank bszámla

adószám bejegyzés

15

Sapientia - Erdélyi Magyar TudományEgyetem (EMTE) Marosvásárhely

Az ábrához tartozó relációk:

Ugyfel(azonosito, nev, adoszam, cim, bejegyzes, bank, bszamla)

Termek(termekID, nev, mertekegyseg)

Szamla(szamlaszam, AFA, datum, hatarido, klienskod)

Szamlasor(szamlaszam, sorszam, egysegar, mennyiseg, termekID)

Mivel a Szamla a bejövő és kimenő számlákat is jelenti, még egy attribútumot adunk hozzá: összeg, amelyik az össz-számlaösszeget jelenti. Ez a kimenő számlák esetében lehet NULL, ezzel meg tudjuk különböztetni a bejövő és kimenő számlákat egymástól.

Szamla(szamlaszam, AFA, datum, hatarido, klienskod, osszeg)

16A megvalósítás ACCESS-ban

17

A számlák kifizetései ugyancsak hasonló a számlasorok struktúrához, mert a kifizetések is egy számlára vonatkoznak. Ezért gyenge egyedhalmaz.

Kifizetes(szamlaszam, sorszam, dokszam, Datum, tipus, összeg)

A tipus lehet pl. {OP, cash} vagy más (kompenzáció) stb.

Ebben nyilvantarthatjuk a mi kifizeteseinket és a nekünk fizetett összegeket is. A különbséget az adja meg, hogy milyen SZÁMLÁHOZ tartozik, a bejövőhöz-e, vagy a kimenőhöz.

számlaszám

Számlák

ÁFA

Dátum

határidőKifizetései

tipús

Sorszám

Kifizetések

összeg

dokSzam

Dátum

18

A kifizetések nyilvántartásával kiegészült ACCESS megvalósítás

19

A kimenő és bejövő számláknak nyilvántartása jobb, ha külön történik: A kimenő számláknál az összeg attribútumot kivettük, mert kiszámítható a számlasorokból. A kifizetéseket is külön vettük.

A beviteli sorrend a következő:

1. Termek, Ugyfel

2. BeSzamla, KiSzamla

3. Szamlasor, bejovoPenz, Kifizetés

20Ugyanaz OpenBaseban

21

CREATE TABLE UGYFEL(azonosito integer PRIMARY KEY,nev VARCHAR(40),cim VARCHAR(40),ADOSZAM VARCHAR(20),BEJEGYZES VARCHAR(20),BANK VARCHAR(50),BANKSZAMLA VARCHAR(40));

CREATE TABLE TERMEK(TERMEKID INTEGER PRIMARY KEY,NEV VARCHAR(50),MERTEKEGYSEG VARCHAR(30));

22

CREATE TABLE BESZAMLA(SZAMLASZAM INTEGER PRIMARY KEY,AFA INTEGER,DATUM DATE,HATARIDO DATE,UGYFELID INTEGER,OSSZEG NUMERIC(16,2),FOREIGN KEY (UGYFELID) REFERENCES

UGYFEL(AZONOSITO));

23

CREATE TABLE KISZAMLA(SZAMLASZAM INTEGER PRIMARY KEY,AFA INTEGER,DATUM DATE,HATARIDO DATE,UGYFELID INTEGER,FOREIGN KEY (UGYFELID) REFERENCES UGYFEL(AZONOSITO));

CREATE TABLE KIFIZETES(SZAMLASZAM INTEGER,SORSZAM INTEGER,DATUM DATE,OSSZEG NUMERIC(16,2),TIPUS VARCHAR(30),PRIMARY KEY(SZAMLASZAM,SORSZAM),FOREIGN KEY (SZAMLASZAM) REFERENCES

BESZAMLA(SZAMLASZAM));

24

CREATE TABLE BEJOVOPENZ(SZAMLASZAM INTEGER,SORSZAM INTEGER,DATUM DATE,OSSZEG NUMERIC(16,2),TIPUS VARCHAR(30),PRIMARY KEY(SZAMLASZAM,SORSZAM),FOREIGN KEY (SZAMLASZAM) REFERENCES

KISZAMLA(SZAMLASZAM));CREATE TABLE SZAMLASOR(SZAMLASZAM INTEGER,SORSZAM INTEGER,EGYSEGAR NUMERIC(16,2),MENNYISEG NUMERIC(16,2),TERMEKID INTEGER,PRIMARY KEY(SZAMLASZAM,SORSZAM),FOREIGN KEY (SZAMLASZAM) REFERENCES

KISZAMLA(SZAMLASZAM),FOREIGN KEY (TERMEKID) REFERENCES TERMEK(TERMEKID));

25

Beviteli sorrend és függőség

Ügyfél Termék

BeSzámla KiSzámla

Kifizetés BejövőPénz Számlasor

1

11

1 1

1

26

1. Melyik ügyfélnek a neve kezdődik ‘A’ betűvel?

SELECT Ugyfel.nev FROM Ugyfel WHERE Ugyfel.nev LIKE ‘A%’;

2. Melyik ügyfél nevében van benne az ‘ama’ betűkombináció?

SELECT Ugyfel.nev FROM Ugyfel WHERE Ugyfel.nev LIKE ‘%ama%’

% mindent helyettesít (mint Windowsban a *)

_ helyettesít egy karaktert (mint Windowsban a ?)

27

Melyik ügyfélhez nem tartozik számla

SELECT Ugyfel.nevFROM UgyfelWHERE Ugyfel.azonosito Not In (SELECT ugyfelID FROM

KiSzamla) And (Ugyfel.azonosito) Not In (SELECT ugyfelID FROM BeSzamla);

Melyik számlához nem tartozik számlasor (ez hiba, vagy még nem vittük be)

SELECT szamlaszamFROM KiSzamlaWHERE szamlaszam NOT IN(SELECT szamlaszam FROM Szamlasor);

Kik a beszállítók (akikhez bejövő számla tartozik)

SELECT DISTINCT Ugyfel.nevFROM Ugyfel INNER JOIN BeSzamla ON

Ugyfel.azonosito=BeSzamla.ugyfelID;

28

Melyik ügyfelek a kliensek (akikhez kimeno szamla tartozik (nem ures))

SELECT DISTINCT Ugyfel.nevFROM Ugyfel INNER JOIN KiSzamla ON Ugyfel.azonosito =

KiSzamla.ugyfelIDWHERE KiSzamla.szamlaszam IN (SELECT szamlaszam FROM Szamlasor);

Melyek azok az ügyfelek, akik egyben beszállítók és vásárlók is

SELECT DISTINCT Ugyfel.nevFROM Ugyfel INNER JOIN KiSzamla ON

Ugyfel.azonosito=KiSzamla.ugyfelIDWHERE szamlaszam IN (SELECT szamlaszam FROM Szamlasor)

ANDazonosito IN (SELECT ugyfelID FROM BeSzamla);

29

SELECT KiSzamla.szamlaszam, Szamlasor.sorszam, Termek.nev, Termek.mertekegyseg, Szamlasor.egysegar, Szamlasor.darabszam, (egysegar)*(mennyiseg) AS sorossz FROM Termek INNER JOIN (KiSzamla INNER JOIN Szamlasor ON KiSzamla.szamlaszam = Szamlasor.szamlaszam) ON Termek.termekID = Szamlasor.termekID;

Számlák a soraikkal együtt.

30

SELECT KiSzamla.szamlaszam, Szamlasor.sorszam, Termek.nev, Termek.mertekegyseg, Szamlasor.egysegar, Szamlasor.darabszam, (egysegar)*(mennyiseg) AS sorosszFROM Termek INNER JOIN (KiSzamla INNER JOIN Szamlasor ON KiSzamla.szamlaszam = Szamlasor.szamlaszam) ON Termek.termekID = Szamlasor.termekIDWHERE (((KiSzamla.szamlaszam)=[Hanyas szamla?]));

Ez a kiegészítés ACCESSben paraméterezett lekérdezést ad. A felhasználótól bekéri a számlaszámot, s csak azt az egy számlát adja meg.

31

SELECT Ugyfel.nev, KiSzamla.szamlaszam, Sum((egysegar)*(mennyiseg)*(1+KiSzamla.AFA/100)) AS osszSzamlaErtek, (Datum)+(hatarido) AS hatardatumFROM Ugyfel INNER JOIN (KiSzamla INNER JOIN Szamlasor ON KiSzamla.szamlaszam=Szamlasor.szamlaszam) ON Ugyfel.azonosito=KiSzamla.ugyfelIDGROUP BY Ugyfel.nev, KiSzamla.szamlaszam, (Datum)+(hatarido);

Megadja minden ügyfélhezt tartozó minden számla összértékét és fizetési határidejét.

32Az előző lekérdezés részleges eredménye (jelentés formájában).

33

Bejövő számláink az ügyfelekkel, összegekkel és határidőkkel

SELECT Ugyfel.nev, BeSzamla.szamlaszam, BeSzamla.osszeg, (Datum)+(hatarido) AS hatardatumFROM Ugyfel INNER JOIN BeSzamla ON Ugyfel.azonosito=BeSzamla.ugyfelID;

Az ügyfelek által vásárolt termékek, mennyiségre:

34

Ha az ügyfeleink által vásárolt termékekről szeretnénk információt fel kell vennünk a lekérdezésbe az összes táblát, amelyen keresztül a kapcsolat megoldható :

SELECT Ugyfel.nev, Termek.nev, Sum(Szamlasor.darabszam) AS SumOfdarabszamFROM Ugyfel INNER JOIN (Termek INNER JOIN (KiSzamla INNER JOIN Szamlasor ON KiSzamla.szamlaszam = Szamlasor.szamlaszam) ON Termek.termekID = Szamlasor.termekID) ON Ugyfel.azonosito = KiSzamla.ugyfelIDGROUP BY Ugyfel.nev, Termek.nev;

Az összekötések zárójelezéssel történnek, amint fentebb a színes kiemelések vannak.

35

Teljesen kifizetetlen számlákSELECT Ugyfel.nev, KiSzamla.szamlaszam, Sum((egysegar)*(mennyiseg)*KiSzamla.AFA/100) AS osszSzamlaErtekFROM Ugyfel INNER JOIN (KiSzamla INNER JOIN Szamlasor ON KiSzamla.szamlaszam=Szamlasor.szamlaszam) ON Ugyfel.azonosito=KiSzamla.ugyfelIDWHERE KiSzamla.szamlaszam NOT IN (SELECT bejovoPenz.szamlaszam FROM bejovoPenz)GROUP BY Ugyfel.nev, KiSzamla.szamlaszam;

Az alkérdés megadja azokat a számlákat, amelyekre kifizetések történtek. Ezeknek a kivonása eredményezi azon számlákat és összegeket, amelyek teljesen kifizetetlenek voltak.

36

Meg szeretnénk tudni, hogyan állnak a részlegesen fizetett számláink is.

Reszlegesen fizetett számlák és a rajtuk levő összeg

SELECT Ugyfel.nev, KiSzamla.szamlaszam, Sum((egysegar)*(mennyiseg)*KiSzamla.AFA/100) AS osszSzamlaErtekFROM Ugyfel INNER JOIN (KiSzamla INNER JOIN Szamlasor ON KiSzamla.szamlaszam=Szamlasor.szamlaszam) ON Ugyfel.azonosito=KiSzamla.ugyfelIDWHERE (((KiSzamla.szamlaszam) In (SELECT bejovoPenz.szamlaszam FROM bejovoPenz)))GROUP BY Ugyfel.nev, KiSzamla.szamlaszam;

Minden számlára az összkifizetés

SELECT bejovoPenz.szamlaszam, Sum(bejovoPenz.osszeg) AS SumOfosszegFROM bejovoPenzGROUP BY bejovoPenz.szamlaszam;

37

A két lekérdezést kombinálva kapjuk meg a tényleges állást

SELECT ReszlegesenFizetettSzamlak.nev, ReszlegesenFizetettSzamlak.szamlaszam, ReszlegesenFizetettSzamlak.osszSzamlaErtek, SzamlaraFizetes.SumOfosszeg, (osszSzamlaErtek)-(SumOfosszeg) AS kulonbsegFROM ReszlegesenFizetettSzamlak INNER JOIN SzamlaraFizetes ON ReszlegesenFizetettSzamlak.szamlaszam = SzamlaraFizetes.szamlaszam;

38

Sapientia - Erdélyi Magyar TudományEgyetem (EMTE) Marosvásárhely

Csak a kifizetetlen számlák, s rajtuk levő összegek

(SELECT *FROM TeljesenKifizetetlenSzamlak)UNION (SELECT nev,szamlaszam,kulonbsegFROM ReszlegesAllasWHERE kulonbseg<>0);

Kik vannak késésben a számla-kifizetéssel

SELECT KiSzamla.szamlaszam, CsakTartozasok.osszSzamlaErtek, (Datum)+(hatarido)AS Expr1FROM KiSzamla INNER JOIN CsakTartozasok ON KiSzamla.szamlaszam=CsakTartozasok.szamlaszamWHERE Datum+hatarido>Date();

39

Sapientia - Erdélyi Magyar TudományEgyetem (EMTE) Marosvásárhely

Kik fizettek egyáltalán késveSELECT Ugyfel.nev, KiSzamla.szamlaszam, bejovoPenz.datum-KiSzamla.datum-[hatarido] AS kesesnap, bejovoPenz.osszegFROM Ugyfel INNER JOIN (KiSzamla INNER JOIN bejovoPenz ON KiSzamla.szamlaszam=bejovoPenz.szamlaszam) ON Ugyfel.azonosito=KiSzamla.ugyfelIDWHERE (((bejovoPenz.datum-KiSzamla.datum-(hatarido))>0));

Recommended