Professional Documents
Culture Documents
SQL-fejtrk
Aki
ebbl
l,
vegye
meg!
Lszl
Leixmte
Levente
ttekints
Elsz
1. fejezet: Adatmeghatrozs
xiii
1
2. fejezet: Adatformzs
33
3. fejezet: Adatkivlaszts
49
4. fejezet: Szmtsok
83
109
Trgymutat
153
Tartalomjegyz
1. fejezet:
Adatmeghatrozs
Denormalizlt adatbzisok
Rossz kdolsi rendszerek
1. feladvny - Tblk ltrehozsa
A megolds
2. feladvny - A munkahelyi tvollt kezelse
1. megolds
2. megolds
3. feladvny - rzstelents
Megolds
4. feladvny - Biztonsgi azonostk
Megolds
5. feladvny - Az adatok formzsa
Megolds
6. feladvny - Szllodai szobafoglals
Megolds
7. feladvny - Iratok
Megolds
1
2
3
3
5
6
7
10
13
15
15
17
17
18
18
19
20
vi
SQL-fejtrk
2. fejezet:
Adatformzs
12. feladvny - Alperesek, llapotok
1. megolds
2. megolds
3. megolds
13. feladvny - Oktatk
1. megolds
2. megolds
14. feladvny - Telefon
Megolds
15. feladvny - A kt legutbbi alapbr
1. megolds
2. megolds
3. megolds
4. megolds
5. megolds
3. fejezet:
24
25
26
27
27
27
28
29
30
31
32
34
36
36
37
38
38
39
40
41
43
44
45
46
47
47
Adatkivlaszts
16. feladvny - Folyamatok
1. megolds
2. megolds
17. feladvny - Munkakzvett iroda
1. megolds
2. megolds
49
50
52
54
55
56
Tartalomjegyzk
3. megolds
18. feladvny - Reklmlevl
1. megolds
2. megolds
19. feladvny - A legjobb rtkestk
Megolds
20. feladvny - Teszteredmnyek
1. megolds
2. megolds
21. feladvny - Replgpek s piltk
1. megolds
2. megolds
22. feladvny - Az dltulajdonos
Megolds
23- feladvny - Folyiratok eladsa
1. megolds
2. megolds
24. feladvny - Tzbl egy
1. megolds
2. megolds
3.megolds
4. megolds
25. feladvny - Mrfldkvek
1. megolds
2. megolds
3. megolds
26. feladvny - Folyamatbrk
1. megolds
2. megolds
3. megolds
27. feladvny - Egyenl halmazok megkeresse
1. megolds
2. megolds
3.megolds
4. megolds
58
58
59
59
60
61
63
63
63
64
64
64
65
66
66
67
68
69
70
70
71
72
72
73
74
74
75
76
77
77
78
79
79
80
81
SQL-fejtrk
4. fejezet:
Szmtsok
28. feladvny - A szinusz fggvny kiszmtsa
1. megolds
2. megolds
29. feladvny - Keressk meg a mduszt!
1. megolds
2. megolds
3. megolds
30. feladvny - tlagos vsrlsi srsg
1. megolds
2. megolds
31. feladvny - Az sszes termk megvsrlsa
1. megolds
2. megolds
32. feladvny - Adszmts
Megolds
33. feladvny - rtkcskkens
Megolds
34. feladvny - Tancsadi djazs
1. megolds
2. megolds
35. feladvny - Ignylsek
1. megolds
2. megolds
36. feladvny - Ktszeres illetk
1. megolds . . .
2. megolds
37. feladvny - Mozg tlag
1. megolds
2. megolds
3. megolds
5. fejezet:
84
84
84
86
86
87
87
88
89
90
90
91
92
92
94
96
97
99
100
101
102
103
104
104
106
106
107
107
108
108
Adatok csoportostsa
38. feladvny - Kltsgvetsi jelents
Megolds
39. feladvny - Halszmlls
1. megolds
110
111
112
113
Tartalomjegyzk
2. megolds
3. megolds
40. feladvny - Diplomaszerzs
41. feladvny - Modellprok
1. megolds
2. megolds
3. megolds
42.feladvny - Pepperoni
1. megolds
2. megolds
43. feladvny - ruhzi akcik
1. megolds
2. megolds
44. feladvny - lhelyszakaszok
1. megolds
2. megolds
45. feladvny - Csoportok felbontsa
1. megolds
2. megolds
46. feladvny - Eszkzgyr
Megolds
47. feladvny - Hrombl kett
1. megolds
2. megolds
3. megolds
48. feladvny - Becslt s tnyleges kltsgek
Megolds
49. feladvny - Szemlyzeti krds
Megolds
50. feladvny - Lovi
1. megolds
2. megolds
51. feladvny - Szllodai szobk
1. megolds
2. megolds
Trgymutat
114
114
115
118
120
121
121
121
122
123
123
125
126
128
128
129
129
130
134
136
137
139
139
140
140
141
143
144
145
147
147
148
148
149
151
153
Eloszo
l
Michael-nek
Az elzmnyek
Tbb mint egy vtizeden t rtam cikkeket szmtstechnikai folyiratokba, de az
olvask csak azokra emlkeznek, amelyek az adatbziskezels s az SQL tmjval
foglalkoztak. Az vek sorn lelkes szszlja lettem az ANSI/ISO szabvnyoknak
s adatbzis-programozsi mdszereknek, s idkzben vilgszerte elismert adat
bzis-felhasznlv vltam. Vagy legalbbis szeretem ezt hinni.
Hrnevemet a Miller Freeman-fle Database Programming & Design folyirat 1990 ja
nuri szmban indul s 1992-ig megjelen Celko on SQL (Celko az SQL-rl) cm
rovattal kezdtem megalapozni. Nhny cikkem mr korbban is megjelent a maga
zinban, ezek biztostottk szmomra a kezdeti figyelmet. Egy rovat esetben a leg
jobb fogs az olvasi visszajelzsek fogadsa - az kevs, ha az olvask ismerik az
embert, valahogy be kell vonni ket a tmba. Valamilyen trkkt kell alkalmazni.
xiv
SQL-fejtrk
Nhny rovat kitallt szereplket sorakoztat fel ebbl a clbl, s egy kis folytat
sos szappanopert hoz gy ltre; msok zleti pletykkkal prblkoznak. Megfon
toltam ezek lehetsgt is, de rjttem, hogy nem tudok sem prbeszdeket, sem
regnyt rni. Ehelyett azt a cselt alkalmaztam, amit mr a korbbi vekben kzlt
rovataimnl is: minden cikkemet egy programozsi feladattal zrtam, aminek meg
oldst az olvasra bztam. A megolds a kvetkez szmban jelent meg, a javasla
tokhoz rt megjegyzsekkel egytt. Az olvask visszajelzsei pozitvnak bizonyul
tak, aminek az oka nyilvnval: a programozk szeretnek problmkat megoldani
- s szeretik a nevket nyomtatsban ltni.
A DBMS magazin (M&T Publishing, amg Miller Freeman meg nem vsrolta) teljes
munkaidre alkalmazott, gy felhagytam a Database Programmng & Desgn-nzk
szabadszknt rt cikkeimmel. 1992 mjusban SQL Explorer cmmel indtottam el
a rovatomat a DBMS-ben. 1996 prilisban a rovat cme SQL for Smarties-ra vlto
zott s a mai napig mkdik. A cikkek vgn lv feladvnyokat megtartottam, de
a szerkeszt kvnsga az volt, hogy a megolds ugyanabban a szmban jelenjen
meg, mint a feladat.
Mialatt a DBMS-n\ dolgoztam, a berlini fal leomlott, Nmetorszg jraegyeslt,
a Deutsche Bank pedig behajtott egy ktelezvnyt az M&T nmetorszgi anyavlla
latval szemben. Hirtelen jra a rgi szerkesztim s bartaim vettek krl. Term
szetesen azonnal felmondtak nekem; vgl is a 80-as veket rtuk, karcsstani, b
vteni vagy racionalizlni kellett mindenkppen. De a rovatomat megtartottam s
tovbb rhattam SQL-feladvnyaimat a cikkekhez.
Ltrehoztam emellett egy msik, SQL-feladvnyokat megjelentet rovatot a Boxes
and Arrows cm, kis pldnyszm szakmai folyiratban, amely az IDMS-szel s
egyb nagygpes adatbziskezel rendszerekkel dolgoz adatbzisfelgyelk,
rendszerelemzk szmra jelent meg. Itt 1989 oktbertl a folyirat 1994 decem
berben trtnt megsznsig jelentek meg a cikkeim.
Elsz
XV
xvi
SQL-fejtrk
A tmakrk
Prbltam fejezeteket kialaktani, hogy a knyv ne pusztn egyms utni feladat
halmazok listjbl lljon. Minden fejezet olyan problmkat tartalmaz, amelyek
megoldsai egy kzs rendezelv kr csoportosthatk. Nmileg nknyesen az
albbi t osztlyt hoztam ltre:
1. Adatmeghatrozs
2. Adatformzs
3. Adatok kivlasztsa
4. Szmtsok vgzse
5. Adatok csoportostsa
E rendszerezs gyengesge, hogy egy feladvny egyes megoldsai klnbz cso
portokba tartozhatnak. Mg rosszabb esetben akr egy megolds is osztlyozhat
tbbflekppen, ha tbbfle fogst alkalmaz. Minden fejezet elejn megprblom
meghatrozni azokat a kzs jellemzket, amelyek meghatrozzk az adott csopor
tot, de mg ez is csak nmileg segt eligazodni. gy csak azt krhetem az Olvastl,
hogy legyen elnz velem szemben.
Elsz
xvii
irt
Joe Celko az Atlantban mkd Northern Lights Software Ltd. tancsadja. 1987tl tagja az ANSI X3H2 adatbzisszabvnyokkal foglalkoz bizottsgnak (ANSI
X3H2 Database Standard Committee), rszt vett az ANSI/ISO SQL-89 s SQL-92
szabvnyok kidolgozsban.
Celko az elmlt 11 vben rendszeresen jelentetett meg cikkeket a szmtstechnikai
magazinok havi vagy ktheti rovataiban. Jelenleg a kvetkez magazinokban van
rovata: DBMS magazin (Miller Freeman) SQL Explorer", Powerbuilder
Developers'
Journal (SysCon) WATCOM SQL Corner", Computing (VNC Publications, UK)
Celko on Software".
Legfrissebb cikkei: Celko on SQL" {Database Programming & Design, Miller
Freeman), SQL Puzzle" {Boxes and Arrows, Frank Sweet Publishing),
DBMS/Report" {System Integration, Cahner-Ziff), Data Desk" {Tech Specialist,
R&D), Data Points" {PC Techniques, Coriolis Group), s a szerkesztje a Puzzles
and Problems" rovatnak is az Abacus cm folyiratban (Springier-Verlag).
XX
SQL-fejtrk
Adatmeghatrozs
Amikor valaki egy SQL-feladvnnyal tallja szemben magt, az els, hogy egy le
krdezst prbl elkpzelni, ami vlaszt ad az adott krdsre. Nagyon gyakran
azonban a gond magukban az adatokban gykerezik, s egy kis vltoztats a tb
ln a bonyolult krdst nagymrtkben leegyszerstheti.
Denormalizlt adatbzisok
Az adatszerkezeti problmknak tbb fajtja ltezik. Tapasztalhatjuk, hogy sokan
a teljestmny javtsa rdekben denormalizljk az adatbzist, de ennek gyakran
ms mdon fizetik meg az rt. Nevezetesen akkor, amikor egy A lekrdezs egy
szerstse cljbl denormalizlt adatbzis a B, c s D lekrdezseket bonyolultt,
megbzhatatlann vagy ppen lehetetlenn teszi. Erre a problmra tbb megolds
is ltezik:
1. Mindig azok legynk, akiknek az A lekrdezst kell megrniuk. Ez sajnos
nem mindig megvalsthat.
2. Hozzunk ltre C H E C K () megszortsokat a denormalizls ltal megsem
mistett kapcsolatok biztostsa cljbl. Ez az SQL-92 szabvny alapjn
mr lehetsges, az albbi kt j jellemznek ksznheten:
Egy tbla C H E C K () megszortsai hivatkozhatnak az adott smban lv
msik tblra. A C H E C K () megszorts tovbbra is egy tblhoz kapcsol
dik s csak akkor kerl sor az ellenrzsre, ha az adott tbla megvltozik.
SQL-fejtrk
1. fejezet Adatmeghatrozs
A megolds
1. Kezdjk a lnyeggel: adjuk minden oszlophoz a N O T N U L L felttelt, hiszen nincs
semmi okunk megengedni, hogy brmelyik mez N U L L rtkkel szerepeljen.
2. A legtbb SQL-programoz azonnal az elsdleges kulcs hozzadsra gondol,
gy legjobb, ha ltrehozzuk a PRIMARY KEY (kvetesiev, kezdodatum, vegda
tum) megszortst, hiszen a kltsgvetsi v valban csak egy msik elnevezse
a (kezdodatum, vegdatum) prosnak. Ez azonban mg kevs, hiszen nem vd
meg az ilyen hibktl:
SQL-fejtrk
(1995,
(1996,
(1997,
(1998,
'1994-10-01',
'1995-10-01',
'1996-10-01',
'1997-10-01',
'1995-09-30')
'1996-08-3 0') <==hiba!
'1997-09-3 0')
'1998-09-30')
1. fejezet Adatmeghatrozs
Ebben az esetben a
CHECK ((vegdatum - kezdodatum) = INTERVAL 359 DAYS)
megszorts meglepen jl mkdik.
Ebben a napok szmt a szablyunkhoz kell igaztanunk (pldul 52 ht * 7 nap =
364 nap). Ha a szablyok megengedik az zleti v hossznak bizonyos mrtk el
trst, az egyenlsg helyett hasznljuk a BETWEEN felttelt.
Egy vallomssal azrt mg tartozom. Amikor egy adatbzisba ilyen tblt kell betltenem, akkor elveszem a SuperCalc programot s annak tblzatkezel fggv
nyeit hasznlva hozom ltre a tblt. A tblzatkezelk ugyanis sokkal jobb idke
zel fggvnyekkel rendelkeznek, mint az adatbziskezelk.
SQL-fejtrk
1. megolds
Az els, az alkalmazottak elbocstsra vonatkoz szablyra pillantva a leggyak
rabban elkvetett tervezsi hiba az, ha megprbljuk kihagyni a tvolltek mso
dik, harmadik s tovbbi napjait a tblbl. Ez a megkzelts sszezavarja azokat
a lekrdezseket, amelyek a betegsgben eltlttt napokat prbljk kivlogatni,
szinte lehetetlenn tve ezen tbbnapos tvolltek megtallst.
A kiskapu az lehet, hogy megengedjk a nulla rtk hibapontot is, gy nyomon
tudjuk majd kvetni a dolgozk hosszabb betegsgeit is a Tvolltek tblban.
Egyszeren cserljk ki a hibapont megadsnl az ellenrzst CHECK (hibapont
BETWEEN 0 AND 4) -re, gy azoknl a tvollteknl, amelyek nem szmtanak bele az
sszegzsbe, nulla rtket is megadhatunk.
UPDATE Tvolltek
SET hibapont = 0,
tvok = 'hosszabb betegsg'
WHERE EXISTS
(SELECT *
FROM Tvolltek AS A2
WHERE Tvolltek.dolgid = A2.dolgid
AND Tvolltek.tavdatum = (A2.tavdatum - INTERVAL 1 DAY));
1 . fejezet Adatmeghatrozs
2. megolds
Bert Scalzo, az ohioi Powellben mkd Oracle Corporation vezet oktatja hvta
fel a figyelmet arra, hogy az elz megoldsnak van kt szpsghibja s a teljest
mnye is nvelhet.
A hibk egyszerek. Elszr is a bels lekrdezs nem ellenrzi, hogy a 40 feletti
pontszmmal rendelkez dolgozk egy ven bell halmoztk-e fel a pontjaikat,
mint ahogy az eredeti feladat-megfogalmazsban szerepelt. Ez egy tovbbi dtum
tartomny-ellenrzst tesz szksgess a WHERE felttelben:
DELETE FROM Dolgozok
WHERE dolgid = (SELECT Al dolgid
FROM Tvolltek AS Al
WHERE Al.dolgid = Dolgozok.dolgid
AND tavdatum
BETWEEN CURRENT_TIMESTAMP
AND CURRENT_TIMESTAMP
- INTERVAL 3 65 DAYS
GROUP BY Al.dolgid
HAVING SUM(hibapont) >= 40);
SQL-fejtrk
1 . fejezet Adatmeghatrozs
10
SQL-fejtrk
3. feladvny - rzstelents
vekkel ezeltt Leonard C. Medl keresett meg ezzel a szellemes kis feladattal.
A krhzakban zajl mttekkor az aneszteziolgus gondoskodik a beteg rzste
lentsrl. Minden rzstelentsi feladatot egy tblban rgztnk.
Folyamatok
feladatjd
10
20
30
40
50
60
70
80
aneszt
'Nyrfs'
'Nyrfs'
'Hartvig'
'Hartvig'
'Hartvig'
'Hartvig'
'Hartvig'
'Hartvig'
kezds
08:00
09:00
09:00
08:00
10:00
12:30
13:30
18:00
befejezs
11:00
13:00
15:30
13:30
11:30
13:30
14:30
19:00
1 . fejezet Adatmeghatrozs
1. bra
feladata.
11
12
SQL-fejtrk
2. bra
feladata.
Jl jegyezzk meg, hogy a helyes vlasz nem az egymst tfed feladatok szma,
hanem ezen feladatok legnagyobb szma.
A krds, hogy mikppen hatrozhatnnk meg ezt az rtket az egyes feladatokra
az SQL segtsgvel. Az albbi tblzat a mintaadatokra meghatrozott eredmnye
ket tartalmazza:
1. fejezet Adatmeghatrozs
feladat
10
20
30
40
50
60
70
80
max_egyideju
2
2
3
3
3
3
2
1
Megolds
Az els lps, hogy minden feladatot kt esemnyre - egy kezdet-esemnyre s
egy vg-esemnyre - bontunk, s az eredmnyt egy nzettblba tesszk. A U N I O N
mvelet (opertor) segtsgvel a kezdet- s vg-esemnyek sszefzhetk, a (+1)
jelenti a kezdet-esemnyt, mg a ( - 1 ) a vg-esemnyt.
A WHERE zradkok biztostjk, hogy az egymssal sszevetett feladatok tfedik
egymst, s mindegyik ugyanahhoz az altatorvoshoz tartozik. A N O T felttel figyel
men kvl hagyja azokat a mtteket, amelyek nincsenek tfedsben a vizsglt aita
tasi feladattal.
CREATE VIEW Esemnyek AS
SELECT Pl.feladat_id AS vizsgalt_feladat,
P2.feladat_id AS hasonltott_feladat,
Pl.aneszt,
P2.kezds AS esemeny_idopont,
+1 AS esemeny_tipus
FROM Feladatok AS Pl, Feladatok AS P2
WHERE Pl.aneszt = P2.aneszt
AND NOT (P2.befejezs <= Pl.kezds
OR P2.kezds >= Pl.befejezs)
UNION
SELECT Pl.feladat_id AS vizsgalt_feladat,
P2.feladat_id AS hasonltott_feladat,
Pl.aneszt,
P2.befejezs AS esemeny_idopont,
-1 AS esemeny_tipus
FROM Feladatok AS Pl, Feladatok AS P2
13
14
SQL-fejtrk
hasonltottJeladat
10
20
10
20
aneszt
Nyrfs
Nyrfs
Nyrfs
Nyrfs
esemenyjdopont
08:00
09:00
11:00
13:00
esemnyJipus
+1
+1
-1
-1
pillanatnyiertek
NULL
1
2
1
1. fejezet Adatmeghatrozs
SELECT vizsgalt_feladat,
MAX(pillanatnyi_ertek) AS max_pill_ert
FROM Egyidejsg
GROUP BY vizsgalt_feladat
ORDER BY vizsgalt_feladat;
Megolds
A feladatlersbl tudjuk, hogy az alkalmazottak azonosti egy kivtellel inaktv l
lapotban vannak. Ennek a felttelnek clszer az adatbzis szintjn rvnyt szerezni.
CREATE TABLE Alkalmazottak
(alk_azon INTEGER PRIMARY KEY,
alk_nev CHAR(30) NOT NULL ,
.. . ) ;
15
16
SQL-fejtrk
A sportszersg kedvrt meg kell jegyeznem, hogy sok SQL-nyelvjrs torkn meg
akad az Azonostok tbla utols C H E C K () zradka az utastsban lv krkrs
hivatkozs miatt, de az SQL-92 szerint szablyos ez az alkalmazsi md. Mellzhet
nnk is ezt az ellenrzst s megengedhetnnk a dolgozknak, hogy ne rendelkez
zenek aktv azonostval. Ezt azt is jelenti, hogy szksgnk lenne egy mdszerre az
alkalmazottak legutoljra kibocstott azonostjnak ' A ' -ra lltshoz.
UPDATE Azonostok
SET llapot = 'A'
WHERE ('I' = ALL (SELECT STATUS
FROM Alkalmazottak AS Bl
WHERE alk_azon = Bl.alk_azon))
AND (kiad_datum = (SELECT MAX (kiad_datum)
FROM Alkalmazottak AS B2
WHERE alk_azon = B2.alk_azon));
Itt ismt figyelmeztetnem kell mindenkit arra, hogy sok SQL-megvalsts fennakad
ezen az UPDATE utastson is a tblanevek azonossga miatt. Az SQL-92 szablya
szerint az UPDATE utastsban lv tblanv hatkre az egsz utastsra kiterjed,
mg az aktulis sor a hivatkozott oszloprtkekre vonatkozik, ezrt a tbla maradk
rsznek megtekintshez a kapcsolt (korrellt) nevekre van szksg. Ezzel az ere
deti lekrdezs igazn knnyv vlik:
SELECT Alkalmazottak.alk_azon, alk_nev, azon_azon
FROM Alkalmazottak, Azonostok
WHERE azon_azon = alkalmazott
AND llapot = 'A';
1. fejezet Adatmeghatrozs
Megolds
Ha alkalmam van, mindig felhvom a figyelmet arra, hogy amikor SQL-ben progra
mozunk, teljes szerkezetben kell gondolkodnunk s nem szabad leragadni a me
zk egyenknti feldolgozsnl. Most a megolds kulcsa a teljes karakterlncban s
nem csak egyetlen karakterben val gondolkods. me a feladatra adott vlasz:
CREATE T A B L E Akrmi
SQL-fejtrk
Megolds
Az egyik megolds olyan SQL-termket ignyel, ami meglehetsen sszetett SQLkifejezst is lehetv tesz a C H E C K () zradkban, ezrt elfordulhat, hogy a meg
valstsok nagy rsze nem fogja tmogatni ezt a mdszert.
1. fejezet Adatmeghatrozs
CREATE
T A B L E Hotel
(SELECT *
FROM Hotel As Hl, Hotel AS H2
WHERE Hl.szobaszm = H2.szobaszm
AND Hl.rkezs
B E T W E E N H2.rkezs AND H2.tvozs))
) ;
7. feladvny - Iratok
Az albbi problmt Steve Tilson kldte el nekem 1995 novemberben:
Van egy feladvnyom a szmodra. Elfordulhat, hogy nem ltom a ftl az erdt,
de szmomra gy tnik, ennek a krdsnek az elegns, krkrs hivatkozsok nl
kli megoldsa igazi kihvs.
20
SQL-fejtrk
Br a felvetett problma teljes rendszernek tnik, n most csak arra lennk kvn
csi, hogy kikszblhetk-e a ltszlagos krkrs hivatkozsok mr a tblaterve
zs szakaszban.
Tegyk fel, hogy egy szervezet iratait kell ksbbi elkeress, jraolvass cljbl
nyilvntartani. Sok klnbz tulajdonsgt troljuk az iratoknak, de a krds
szempontjbl csak nhnynak van jelentsge:
C R E A T E TABLE Iratok
Megolds
Steve mg mindig eljrsokban s mutatlncokban gondolkodik. Szgyellheti ma
gt! Mi mr tudjuk, hogy a krds a sorszmokkal kapcsolatos, hiszen a feladatle
rsban elbjtatva ott az rulkod kt sz: eld s utd. Alkalmazzuk, amit az egy
msba gyazott halmazokrl (nested sets) tanultunk.
1 . fejezet Adatmeghatrozs
Elszr is hozzunk ltre egy tblt, amiben troljuk egy akta minden adatt:
CREATE TABLE Iratok
(akta_id INTEGER NOT NULL PRIMARY KEY,
egyeb_anyag . . . . ) ;
INTO
INTO
INTO
INTO
INTO
INTO
INTO
Iratok
Iratok
Iratok
Iratok
Iratok
Iratok
Iratok
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
(222,
(223,
(224,
(225,
(322,
(323,
(324,
'anyag');
'rgi anyag');
'j anyag');
'klcsnkrt anyag')
'kk anyag');
' lila anyag');
'piros anyag');
21
22
SQL-fejtrk
INTO
INTO
INTO
INTO
Sorrend
Sorrend
Sorrend
Sorrend
VALUES
VALUES
VALUES
VALUES
(1,
(1,
(1,
(1,
0,
1,
2,
3,
222,
223,
224,
225,
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INTO
INTO
INTO
INTO
INTO
INTO
INTO
Sorrend
Sorrend
Sorrend
Sorrend
Sorrend
Sorrend
Sorrend
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
(2,
(2,
(2,
(2,
(2,
(2,
(2,
0,
1,
2,
3,
4,
3,
5,
322,
323,
324,
322,
323,
999,
999,
'1995- 11 -01'
'1995- 11 -02 '
'1995- 11 -04 '
' 1995-11 -05 '
' 1995-11 -12 '
' 1995-11 -25 '
' 1995-11 -25 '
23
1 . fejezet Adatmeghatrozs
A gond itt az, hogy megengedtem, hogy egyetlen akta tbb aktt is hatlytalant
son, vagy hogy tbb akta hatlytalanthasson egyetlen iratot. A lncaim nem eg
szen linerisak; a kd elszll, ha a : regi_akta_id tbb lncban is szerepel. A hi
ba kijavthat a lncok szmnak vagy az j akta ltal hatlytalantott irathoz
tartoz akta_id lekrdezsvel, de az SQL-kd elg csnya. Meg lehet prblni
a finomtst!
24
SQL-fejtrk
(felhasznalo_id C H A R ( 2 0 ) ,
nyomtato_nev C H A R ( 2 0 ) N O T N U L L ,
leiras C H A R ( 4 0 ) N O T N U L L ) ;
nyomtatonev
'LPT1'
'LPT2'
'LPT3'
'LPT4'
'LPT5'
25
1 . fejezet Adatmeghatrozs
Megolds
Azt kell vlaszolnom, hogy a hiba az adatokban van. Nzznk a f elhasznalo_id
oszlopot. Mr a neve is mutatja, hogy mezinek egyedinek kell lennik, a N U L L r
tk mgis tbbszr elfordul. A valsgban egy msik gond is jelentkezik: a nyom
tatk terhelst nyilvn gy szeretnnk megosztani az LPT4 s LPT5 nyomtatk k
ztt, hogy egyik se legyen tlterhelve.
Ne talljunk ki semmilyen szellemes lekrdezst - vltoztassuk meg a tblt:
CREATE TABLE NyomtatoVezerlo
(felhasznalo_tol CHAR(8) NOT NULL,
felhasznalo_ig CHAR(8) NOT NULL,
nyomtato_nev CHAR(4) NOT NULL,
leiras CHAR(40) NOT NULL,
PRIMARY KEY (felhasznalo_tol, felhasznalo_ig));
Most pedig vizsgljuk meg az albbi pldt:
NyomtatoVezerlo
felhasznatotoi
'chacha'
'lac'
'tomi'
'aaaaaaaa'
'naaaaaaa'
fethasznaiojg
'chacha'
'lac'
'tomi'
'mzzzzzzz'
'zzzzzzzz'
nyomtatojiev
'LPT1'
'LPT2*
'LPT3'
'LPT4'
'LPT5'
leiras
'Els emeleti nyomtat'
'Msodik emeleti nyomtat'
'Harmadik emeleti nyomtat
'j felhasznl nyomtatja'
'j felhasznl nyomtatja'
26
SQL-fejtrk
1 . fejezet Adatmeghatrozs
1. megolds
Az llapotjelzt kpviselheti egy pozitv vagy negatv eljel az lhely azonost
szmnak mezjben, ezzel megtakartunk egy oszlopot, de ez nagyon rossz elj
rs az adatbzis logikjnak szempontjbl, hiszen kt tulajdonsg olvad ssze
egyetlen mezv. Radsul az 1000 sor is megmarad a tblban.
2. megolds
A msodik gondolat az, hogy hozzunk ltre egy tovbbi, egyetlen oszlopot tartal
maz tblt a foglalt helyek nyilvntartsra s mozgassuk a szmokat a foglalt s
a szabad helyek tbli kztt. Ez a megolds a kt tblban sszesen ignyelne
1000 rekordot.
3. megolds
Inkbb hasznljunk egyetlen tblt s rendeljk a szmokat 0-tl 1001-ig az lhe
lyekhez (a 0 s az 1001 igazbl nem ltezik, s ezeket sohasem adjuk ki a vend
geknek). Trljk a helyet a tblbl, ha elfoglaljk, s rjuk vissza, ha megint sza
badd vlik. Amikor az sszes hely foglalt, az tterem tbla lehet olyan kicsi,
amekkora helyet a kt nem valdi sor elfoglal, de a rekordok szma semmikppen
sem lehet tbb 1002-nl (ez a teljesen res tterem esete).
Az albbi nzettbla megkeresi az els helyet a szabad helyek egyik rsben:
CREATE VIEW Elso_hely (hely)
AS SELECT (hely + 1)
FROM tterem
WHERE (hely + 1) NOT IN
(SELECT hely FROM tterem)
AND (hely + 1) < 1001;
Hasonlan, az albbi nzettbla megkeresi az utols helyet a szabad helyek egyik
rsben:
CREATE VIEW Utolso_hely (hely)
AS SELECT (hely - 1)
FROM tterem
27
28
SQL-fejtrk
1. fejezet Adatmeghatrozs
1. megolds
Az albbi lekrdezs megadja annak az sszefgg idszaknak a kezd s befejez
vt, amikor (1) a munkavllal dolgozott (a szolglatban tlttt hnapok szma 0nl nagyobb) s (2) a munkaviszonyban tlttt hnapok szmnak sszege 60
vagy annl tbb.
CREATE VIEW Nyugldoszakok (tb_azon, kezdo_ev, utolso_ev,
ossz_jovedelem)
AS SELECT P0.tb_azon, P0.nyug_ev, Pl.nyug_ev,
(SELECT SUM (jvedelem) -- az idszak sszjvedelme
FROM Nyugdijak AS P2
WHERE P2.tb_azon = P0.tb_azon
AND P2.nyug_ev BETWEEN P0.nyug_ev AND Pl.nyug_ev)
FROM Nyugdijak AS PO, Nyugdijak AS Pl
WHERE Pl.tb_azon = P0.tb_azon - n-sszekapcsols az idszak
ltrehozshoz
AND Pl.nyug_ev >= (P0.nyug_ev - 4) -- mirt korbban?
AND 0 < ALL (SELECT szolg_ho -- folyamatos munkaviszony
FROM Nyugdijak AS P3
WHERE P3.tb_azon = P0.tb_azon
AND P3.nyug_ev
BETWEEN P0.nyug_ev AND Pl.nyug_ev)
AND 60 <= (SELECT SUM (szolg_ho) -- az sszeg tbb 60-nl
FROM Nyugdijak AS P4
WHERE P4.tb_azon = P0.tb_azon
AND P4.nyug_ev
BETWEEN P0.nyug_ev AND Pl.nyug_ev);
29
30
SQL-fejtrk
2. megolds
A legtbb tovbbfejlesztett megolds, amelyet a CompuServe-n keresztl kaptam,
az n eredeti megoldsomra plt. Viszont Richrd Romley megoldsa, ami a leg
jobbnak bizonyult, teljesen ms oldalrl kzelti meg a krdst. me az lekrdezse:
SELECT Kezd.tb_azon,
Kezd.nyug_ev AS kezdo_ev,
Bef.nyug_ev AS zaro_ev,
SUM (Kozep.jovedelem)
FROM Nyugdijak AS Kezd, Nyugdijak AS Kozep, Nyugdijak AS Bef
WHERE Kezd.szolg_ho > 0
AND Kozep.szolg_ho > 0
AND Bef.szolg_ho > 0
AND Kezd.tb_azon = Kozep.tb_azon
AND Kezd.tb_azon = Bef.tb_azon
AND Kezd.nyug_ev BETWEEN Bef.nyug_ev-59 AND (Bef.nyug_ev - 4)
1 . fejezet Adatmeghatrozs
31
32
SQL-fejtrk
llapot
'O
R
*R'
'R
R
'C
'C
menet
0
1
2
0
1
0
1
Megolds
Valjban egszen egyszer a megolds, de ahhoz, hogy a vlaszt lssuk, t kell fo
galmazni a lekrdezs meghatrozst. Ahelyett, hogy azt mondjuk, az adott mun
karend minden ms menet-rtkhez R llapot tartozzon", legyen a megfogalma
zs a kvetkez: az sszes nem nulla menetnek ' R' legyen az llapota",
gy a megolds szinte az lnkbe pottyan:
1
SELECT munkarend
FROM Projektek AS Pl
WHERE menet = 0
AND llapot = 'C
AND 'R' = ALL (SELECT llapot
FROM Projektek AS P2
WHERE menet <> 0
AND Pl.munkarend = P2.munkarend);
Adatformzs
Azzal szoktunk trflkozni, hogy az SQL rvidts mgtt valjban a Scarcely
Qualifies as a Language" (Nemigen nevezhet nyelvnek") kifejezs ll, mert csu
pn egy adatbzis-lekrdez nyelvrl van sz. Az SQL ANSI/ISO szabvnyban az
egyetlen bemeneti utasts az I N S E R T I N T O , s valdi kimeneti fggvny nincs is.
A lekrdezs eredmnyt a gazdaprogramnak adjuk t, ennek a feladata ezutn
a megjelents kezelse.
A C A S T () fggvnnyel lehetsgnk van egyik adattpusbl egy msikba talakta
ni egy rtket vagy korltozott mrtkben karakterlnc-mveleteket is vgezhe
tnk, de nem hatrozhatjuk meg gy az adatok megjelentsi formjt, mint ahogy
a hagyomnyos programozsi nyelvekben - Cobol, Fortran, PL/I, BASIC stb. - te
hetjk. Az SQL egyszeren nem rendelkezik olyan utastsokkal, mint a Cobolban
a P I C T U R E , a Fortranban a F O R M T vagy a PL/I-ben a P U T EDIT.
Tallkozhatunk olyan termkekkel, amelyek rendelkeznek a bels adattpusokat
formzott karakterlncc talaktani kpes fggvnyekkel, de ezek nem rszei
az ANSI/ISO szabvnynak. Ha utnozni akarjuk a Fortran F O R M T vagy a Cobol
P I C T U R E utastst a szabvnyos SQL-ben, gyakran kellene a C A S T () s
S U B S T R I N G () fggvnyeket, karakterlnc-sszefzst s egyb ehhez hasonl
mveleteket alkalmaznunk.
34
SQL-fejtrk
beteg
'Kovcs'
'Jakab'
'Szab'
Minden keresethez egy vagy tbb alperes, ltalban orvos tartozik, akiket
a Kereset alperes tblban trolunk:
Keresetalperes
kereset id
10
10
10
20
20
30
'Vradi'
'Mjer'
'Takcs'
'Nyrfs'
'Mjer'
'Vradi'
2. fejezet Adatformzs
Esemnyek
keresetJd
lu
10
10
10
10
10
10
10
10
20
20
20
30
alperes
'Vradi'
'Vradi'
'Vradi'
'Vradi'
'Mjer'
'Mjer'
'Mjer'
'Takcs'
'Takcs'
'Mjer'
'Mjer'
'Nyrfs'
'Vradi'
llapot
vv
VB'
'KI'
'LZ'
'W
'VB'
'KI'
'W
'VB'
W
VB'
W
'W
vattdatum
'1994-01-01'
'1994-02-01'
'1994-03-01'
'1994-04-01'
'1994-01-01'
'1994-02-01'
'1994-03-01'
'1994-01-01'
'1994-02-01'
'1994-01-0r
1994-02-01'
'1994-01-01'
'1994-01-01'
altepotleir
A zsgalobizoltsagiu \ -r'
'Bizottsg;i vlemny benyjtva'
'A kereset iktatva'
'Lezrva'
sorszm
1
2
3
4
Egy alperes llapota (az adott keresettel kapcsolatban) a hozz rendelt legutols,
legmagasabb sorszmmal rendelkez llapot. Bizonyos jogszablyi okokbl kifo
lylag az esemnyek dtum szerinti sorrendje nem mindig fedi a sorszm szerinti
sorrendet.
Egy kereset llapota annak az alperesnek az llapott jelenti, aki a keresetben rin
tett szemlyek kzl a legkisebb sorszm llapottal rendelkezik. Ezzel egy kereset
llapota tulajdonkppen az llapotsorszmok legnagyobb rtkei kzl a legkisebb.
A pldnkban szerepl adatokra adott vlasz a kvetkez lenne:
36
SQL-fejtrk
keresetjd
10
20
30
beteg
'Kovcs'
'Jakab'
'Szab'
aflapot
'VB'
W
'W
1. megolds
Medal vlasza egyetlen SQL-lekrdezs, ami a lerst kzvetlenl kdd fordtja le:
SELECT Cl.kereset_id. Cl.beteg, T2.llapot
FROM Keresetek AS Cl, AllapotKodok AS T2
WHERE T2.sorszm
IN (SELECT MIN(S2.sorszm)
FROM AllapotKodok AS S2
WHERE S2.sorszm
IN (SELECT MAX(S3.sorszm)
FROM Esemnyek AS El, AllapotKodok AS S3
WHERE El.llapot = S3.llapot
AND El.kereset_id = Cl.kereset_id
GROUP BY El.alperes));
2. megolds
Ltezik ms megolds is. Knnyebb kinyerni azon llapotok kdjait egy kereset
ben, amelyeket minden alperes elrt mr:
SELECT
FROM
WHERE
GROUP
HAVING
2. fejezet Adatformzs
3. megolds
Sorin Shtirbunak ksznhetjk a harmadik megoldsi mdszert:
SELECT kereset_id, MAX(beteg), MAX(TI.llapot)
FROM llapot AS TI, Keresetek AS Cl
WHERE TI.sorszm =
(SELECT MAX(T2.sorszm)
FROM llapot AS T2, Esemnyek AS El
WHERE T2.llapot = El.llapot
AND El.kereset_id = Cl.kereset_id
GROUP B Y El.kereset_id, alperes)
GROUP B Y kereset_id, TI.sorszm
HAVING Tl.sorszm = MIN(TI.sorszm);
Felmerl a krds, hogy vajon ezzel a harmadik megoldssal n-e a hatkonysg.
Valsznleg ez fgg az indexelsi mdtl, s attl is, hogy az adott SQLalkalmazs hogyan kezeli a bels lekrdezseket s a G R O U P B Y zradkot.
37
38
SQL-fejtrk
1. megolds
J mdszer lehet a szlsrtk-fggvnyek hasznlata.
SELECT
FROM
GROUP
HAVING
UNION
2. fejezet Adatformzs
2. megolds
Richrd S. Romley jfent tltett a nyomtatsban megjelent megoldsomon, azzal
a fogssal, hogy a kt S E L E C T utastst egy C A S E kifejezsben hasznlt szlsrtk
fggvnny srtette, az SQL-92 szablyai szerint:
SELECT kurzus, hallgat, MIN(oktato),
CASE COUNT(*) WHEN 1 THEN NULL
WHEN 2 THEN MAX(oktat)
ELSE '--Tbb-FROM Nyilvntarts
GROUP BY kurzus, hallgat;
1
39
40
SQL-fejtrk
A C A S E kifejezsnek ez a tpusa gondokat okozhat a jelenlegi SQL-alkalmazsokban. Nhny rgebbi SQL-megvalstsbl teljesen hinyoznak a C A S E kifejezsek,
egyesek pedig sszegz fggvnyek hasznlatt nem teszik lehetv a C A S E kifeje
zsen bell. A kifejezsnek ez a formja trhat egy ezzel teljesen egyenrtk
utastsformra:
CASE WHEN COUNT(*) = 1 THEN NULL
WHEN C0UNT(*) = 2 THEN MAX(oktat)
ELSE '--Tbb--'
2. fejezet Adatformzs
Megolds
A lekrdezs egy sor hibalehetsget hordoz magban. Az els gondolat az otthoni
telefonok adatainak kln lekrdezsbe foglalsa. Mivel minden alkalmazottat ltni
szeretnnk, egy kls sszekapcsols ( O U T E R J I N ) hasznlatra van szksgnk:
CREATE VIEW Otelefonok (vezetknv, keresztnv, alk_id,
otthoni_szam)
AS SELECT El.vezetknv, El.keresztnv, El.alk_id, Hl.telefonszm
FROM (Alkalmazottak AS El
LEFT OUTER JIN
Telefonok AS Hl
ON El.alk_id = Hl.alk_id AND Hl.telefontipus = 'ott');
Ugyanezzel a megkzeltssel llthatjuk el a faxok adatait egy msik lekrdezssel:
CREATE VIEW Ftelefonok (vezetknv, keresztnv, alk_id, faxszm)
AS SELECT El.vezetknv, El.alk_id, FI.telefonszam
FROM (Alkalmazottak AS El
LEFT OUTER JIN
Telefonok AS FI
ON El.alk_id = Fl.alk_id AND FI.telefontipus = 'fax');
Indokoltnak ltszik a kt nzettbla sszevonsa, ami az albbi eredmnyt adja:
SELECT Otelefonok.vezetknv, Otelefonok.keresztnv, otthoni_szam,
faxszm
FROM Otelefonok AS Hl, Ftelefonok AS FI
WHERE Hl.alk_id = Fl.alk_id;
41
42
SQL-fejtrk
Sajnos ez a megolds sem jelenti meg a csak faxszmmal rendelkezk nevt, ame
lyek gy resen maradnak, mert csak az otelefonok tblban lv nevek kiratst
tartalmazza a lekrdezs. Ezt a problmt a C O A L E S C E () fggvny oldja meg sz
munkra. Ez a paramterknt kapott kifejezslistbl balrl jobbra haladva az els
nem NULL rtkkel tr vissza:
SELECT COALESCE (Hl.vezetknv, FI.vezetknv),
COALESCE (Hl.keresztnv, FI.keresztnv),
otthoni_szam, faxszm
FROM Otelefonok AS Hl
FULL OUTER JIN
Ftelefonok AS Fl
ON Hl.alk_id = Fl.alk_id;
Ez mkdik ugyan, de futsrl nemigen, inkbb csak vnszorgsrl beszlhetnk,
mert alighanem ellltja a nzettblkat, mieltt hasznln azokat. A megnyugtat
megoldst akkor lelhetjk meg, ha visszatrnk az Ftelefonok s otelefonok n
zettblkban lv OUTER JIN kapcsolatokhoz. Innen kiemelhetjk az Alkalma
zottak tbla kapcsolatt s az albbi mdon sszevonhatjuk a kt F R O M zradkot:
SELECT El.vezetknv, El.keresztnv,
Hl.telefonszm AS Otthon,
Fl.telefonszm AS FAX
FROM (Alkalmazottak AS El
LEFT OUTER JIN
Telefonok AS Hl
ON El.alk_id = Hl.alk_id AND Hl.telefontipus = 'ott')
LEFT OUTER JIN
Telefonok AS Fl
ON El.alk_id = Fl.alk_id AND Fl.telefontipus = 'fax';
Mivel a lekrdezs minden tblt elsre megkap, gyorsabbnak kell lennie, mint
a rossz kiindulssal ellltott megolds. Ez megint egy olyan lekrdezs, amit nem
knny tltetni a Sybase, Oracle vagy Gupta stlus O U T E R J I N formtumra, mi
vel ezek az SQL-ek nem kezelik a begyazott O U T E R J I N kapcsolatokat.
2. fejezet Adatformzs
43
SQL-fejtrk
44
1. megolds
Elszr oldjuk meg a krds knny felt. A megolds annak a lekrdezsnek
a hasznlata, amit ltalnos szlsrtknek, vagy els(n) fggvny"-nek szoktam
nevezni. Helyezzk ezt egy nzettblba:
CREATE VIEW Fizetesekl (alkalm, jel_fiz_datum, jel_fiz_osszeg)
AS SELECT SO.alkalm, SO.fiz_datum, MAX(SO.fiz_osszeg)
FROM Fizetsek AS SO, Fizetsek AS SI
WHERE SO.fiz_datum >= SI.fiz_datum
GROUP BY SO.alkalm, SO .fiz_datum
HAVING COUNT(*) <= 2;
CREATE VIEW Fizetesek2 (alkalm, fiz_datum, fiz_osszeg)
AS SELECT SO.alkalm, SO.sal_date, MAX(SO.fiz_osszeg)
FROM Fizetsek AS SO, Fizetsek AS SI
WHERE SO.fiz_datum <= SI.fiz_datum
AND SO.alkalm = Sl.alkalm
GROUP BY SO.alkalm, SO .fiz_datum
HAVING COUNT(*) <= 2;
Eredmnyek
alkalm
'Ferenc'
'Kroly'
'Kroly'
'Tams'
'Tams'
fizdatum
'1996-06-20'
'1996-07-20'
'1996-09-20'
'1996-10-20'
'1996-12-20'
fizosszeg
500.00
500.00
700.00
800.00
900.00
2. fejezet Adatformzs
2. megolds
A valdi problma egy kicsit bonyolultabb. Az SQL-89 korltai kzt mozogva a kr
ds egyik megoldsa az esetek kt csoportra osztsa:
1. Alkalmazottak csupn egyetlen brvltozssal.
2. Alkalmazottak kett vagy annl tbb brvltozssal.
Abban biztosak lehetnk, hogy minden alkalmazott beleesik az egyik, de csak az
egyik csoportba. Az egyik megolds e kt csoport egyestse lehet a UNION utastssal:
SELECT SO.alkalm, SO.fiz_datum, SO.fiz_osszeg, Sl.fiz_datum,
^ Sl.fiz_osszeg
FROM Fizetsek AS SO, Fizetsek AS Sl
WHERE SO.alkalm = Sl.alkalm
AND SO.fiz_datum =
(SELECT MAX(S2.fiz_datum)
FROM Fizetsek AS S2
WHERE SO.alkalm = S2.alkalm)
AND Sl.fiz_datum =
{SELECT MAX(S3.fiz_datum)
FROM Fizetsek AS S3
WHERE SO.alkalm = S3.alkalm
AND S3.fiz_datum < SO.fiz_datum)
UNION ALL
SELECT S4.alkalm, MAX(S4.fiz_datum) , MAX(S4.fiz_osszeg) , NULL,
NULL
FROM Fizetsek AS S4
GROUP BY S4.alkalm
HAVING COUNT(*) = 1;
45
46
SQL-fejtrk
alkalm
'Tams'
'Kroly'
'Ferenc'
fizdatum
'1996-12-20'
'1996-09-20'
'1996-06-20'
fizosszeg
900.00
700.00
500.00
fizdatum
'1996-10-20'
'1996-07-20'
NULL
fizosszeg
800.00
500.00
NULL
3. megolds
Tbb javtott megoldst is kaptam vlaszknt a prblkozsaimra. A Smith Barney
alkalmazsban ll Richrd Romley a kvetkez SQL-92 megoldst kldte. Ez ki
hasznlja a bels lekrdezs elnyeit a nzettblk elkerlsre:
SELECT B.alkalm, B.maxdatum, Y.fiz_osszeg, B.maxdatum2,
W Z.fiz_osszeg
FROM (SELECT A.alkalm, A.maxdatum, maxdatum2 = MAX(X.fiz_datum)
FROM (SELECT W.alkalm, maxdatum = MAX(W.fiz_datum)
FROM Fizetsek AS W
GROUP BY W.alkalm) AS A
LEFT OUTER JIN Fizetsek AS X
ON A.alkalm = X.alkalm
AND A.maxdatum > X.fiz_datum
GROUP BY A.alkalm, A.maxdatum) AS B
LEFT OUTER JIN Fizetsek AS Y
ON B.alkalm = Y.alkalm
AND B.maxdatum = Y.fiz_datum
LEFT OUTER JIN Fizetsek AS Z
ON B.alkalm = Z.alkalm
AND B.maxdatum2 = Z.fiz_datum;
2. fejezet Adatformzs
Ha az ltalunk hasznlt SQL nem tmogat mst, csak a tbla- vagy nzettbla
neveket az OUTER JIN kifejezsben, az A s B nev allekrdezseket trhatjuk
nzettblkk.
4. megolds
Mike Conway egy Oracle-re rt megoldssal llt el, amit tbb-kevesebb sikerrel t
ltettem az SQL-92 szabvny szerint. Az tltets nehzsge az volt, hogy az Oracle
ltal hasznlt SQL nem tmogatja az SQL-92 szerinti O U T E R J I N formtumot, gy fi
gyelni kell a futtatsi sorrendre ahhoz, hogy a megfelel eredmnyt kapjuk. Syed
Kadir, az Oracle szoftvermrnke megoldsom egy tovbbfejlesztett vltozatt
kldte el, ami az els megoldsban alkalmazott nzettblt hasznlja:
SELECT Sl.alkalm, Sl.fiz_datum, Sl.fiz_osszeg, S2.fiz_datum,
S2.fiz_osszeg
FROM Fizetesekl A S Sl, Fizetesek2 AS S2 - a nzettbla hasznlata
WHERE Sl.alkalm = S2.alkalm
AND Sl.fiz_datum > S2.fiz_datum
UNION ALL
SELECT alkalm, MAX(fiz_datum). MAX(fiz_osszeg), NULL, NULL
FROM Fizetesekl
GROUP BY alkalm
HAVING COUNT(*) = 1 ;
5. megolds
Richrd Romley-val hosszasan leveleztnk a feladatra adhat egyb megoldsokkal
kapcsolatban, mg mindketten ugyanarra a hagyomnyoktl elszakadt megkzel
tsre jutottunk, amit formai megfontolsok miatt el akartam vetni. Vgl gy dn
tttem, a teljestmny legyen a dnt sz.
47
48
SQL-fejtrk
Adatkivlaszts
Rendszerint megemltem az SQL-eladsaim hallgatinak, hogy a nyelvet nagyon
knny elsajttani, mert a S E L E C T . . . F R O M . . . utastsok a munka 90%-t lefe
dik. Tanuljunk meg egyetlen utastst s mris komoly hatalommal rendelkeznk
egy j programozsi nyelv felett. Persze ez olyan, mintha azt mondannk, hogy
a LISP egyszer, hiszen minden program csupn egy fggvnyhvsbl ll.
A csapda termszetesen ott rejtzik, hogy egyetlen S E L E C T utasts is lehet annyira
sszetett, nyakatekert s bonyolult, mint brmely eljrskzpont program.
A most kvetkez feladvnyok alapja egy olyan szellemes mdszer a tblk bizo
nyos adatainak kiszrsre, ami els rnzsre esetleg nem teljesen nyilvnval.
50
SQL-fejtrk
nem normalizlnak. Ezzel viszont a feladat nem lett volna megoldva, msrszt az
ARI-hoz hasonl hozzllssal idrl idre szembetallkozom a vals problmk
megoldsa sorn.
A rendszer az alkalmazottak egyes feladatok vgrehajtsra ltrehozott csoportjait
kveti nyomon. Minden feladathoz tartozhat pontosan egy elsdleges (primary) fo
lyamat s egyetlen segd- (assistant) folyamat. A krdses tblk az albbi mdon
plnek fel:
C R E A T E T A B L E Feladatok
1. megolds
Az els feladat a hivatkozsi psg biztostsa. A Csoportok tbla valsznleg
F O R E I G N K E Y hivatkozsokon keresztl ms tblkhoz kapcsoldik, de sohasem
rthat, ha egy adatbzisban vgrehajtjuk az albbi ellenrzseket:
3. fejezet Adatkivlaszts
Csoportok.feladat_id
= 'Primary') AS "Primary",
Csoportok.feladat_id
= 'Assistant') AS Assistant
51
52
SQL-fejtrk
Feladatok.feladat_id,
(SELECT nev
FROM Csoportok, Alkalmazottak
WHERE Feladatok.feladat_id = Csoportok.feladat_id
AND Alkalmazottak.alk_id = Csoportok.alk_id
AND Csoportok.folyamattipus = 'Primary') AS "Primary",
(SELECT nev
FROM Csoportok, Alkalmazottak
WHERE Feladatok.feladataid = Csoportok.feladat_id
AND Alkalmazottak.alk_id = Csoportok.alk_id
AND Csoportok.folyamattipus = 'Assistant') AS Assistant
FROM Feladatok;
Ha olyan alkalmazottunk van, aki egy feladat elsdleges s msodlagos folyamat
ban is rszt vesz, akkor szerepelni fog mindkt helyen. Ha kett vagy annl tbb
elsdleges folyamat, vagy kett vagy tbb segdfolyamat tartozik egy feladathoz,
akkor hibazenetet kapunk - ahogy az el is vrhat. Ha nincs elsdleges vagy se
gdfolyamat, res eredmnyt kapunk N U L L rtk formjban. Ezzel el is jutottunk
a kvnt OUTER JIN eredmnyekhez.
2. megolds
Skip Lees a kaliforniai Chicobl a Csoportok tblra az albbi szablyok rvnye
stst szorgalmazta:
1. Egy f eladat_id rtkhez nulla vagy egy elsdleges folyamat tartozik.
2. Egy f eladat_id rtkhez nulla vagy egy segdfolyamat tartozik.
3- Egy f eladat_id rtkhez legalbb egy (valamelyik tpus) folyamatnak
tartoznia kell.
A 3. szably szerint nem lehet olyan pillanat, amikor egy feladat nem rendelkezik
csoporttagokkal. Emiatt a csoportinformcikat mg a feladat rekordjnak ltreho
zsa eltt rgzteni kell a rendszerben. Egy hivatkozsipsg-ellenrzssel rvnyre
juttathat ez a megszorts. Az 1. s 2. korltozs a feladat_id s a folyamat
tipus ktoszlopos elsdleges kulccs nyilvntsval kiknyszerthet, gy egy
adott folyamattpushoz ugyanaz a feladatazonost nem vihet fel ismtelten.
3. fejezet Adatkivlaszts
C R E A T E T A B L E Feladatok
53
54
SQL-fejtrk
3. fejezet Adatkivlaszts
(Cl.szakismeret_kod = 'gyrts'
A N D C2.szakismeret_kod = 'raktrozs'
OR C3.szakismeret_kod = 'knyvels')
Egy j PowerBuilder- vagy Delphi-programoz egy hten bell elkszti azt az rla
pot, ami elvgzi ezt a feladatot. Ezutn a munka_id kdjnak neve alatt nzettbla
knt mentjk a lekrdezst. Szellemes s gyors megolds! A baj csak az, hogy ezzel
a mdszerrel hatalmas mennyisg nagyon lass lekrdezsnk lesz.
Nincs valami jobb tlet? Elfelejtettem emlteni, hogy a kezelend tevkenysgek
szma 250 ezer fltt van. Az iroda a DOT-rendszert (Dictionary of Occupational
Titles, a magyar TEOR szerinti tevkenysgkd Egyeslt llamokban hasznlt
megfelelje a ford) hasznlja a nyilvntartshoz, ami az llamokban statisztikai
clokat szolgl.
1. megolds
Ha nem kellene ennyi tevkenysggel megkzdennk, a megolds sokkal egysze
rbb lenne. Egy egsz szmot hasznlhatnnk gy, mint egy bitekbl ll karakter
lncot, s ennek minden pozcijt 0-ra vagy l-re llthatnnk a tevkenysgnek
megfelelen. Pldul:
'knyvels' = 1
raktrozs' = 2
'gyrts' = 4
stb.
1
gy a ( ' knyvels ' A N D ' gyrts ' ) brzolhat lenne a (2+4) = 6 formban.
Sajnos negyedmilli ttel esetn ez a fajta megkzelts nem mkdik.
Az els gond, ami itt addik, a keressi felttel rtelmezsvel kapcsolatos.
A gyrts s raktrozs vagy knyvels" vajon a kigyjts sorn gy rtelmezend,
hogy (gyrts A N D raktrozs) OR knyvels vagy gyrts A N D (raktrozs
OR knyvels) ? ljnk a felttelezssel, hogy az A N D mvelet elsbbsget lvez az
rtelmezskor.
55
56
SQL-fejtrk
2. megolds
Egy msik megolds az, hogy minden lekrdezst diszjunktv kanonikus forma sze
rint runk t, ami magyarul annyit jelent, hogy a keressi felttelek AND mveletek
kel sszekapcsolt karakterlncok formjban megadott kritriumok, majd a legfel
sbb szinten ezeket kapcsoljuk egymshoz az OR mvelettel.
Hozzunk ltre a munkarendelsek szmra egy msik tblt, amit adatokkal tlthe
tnk fel:
CREATE TABLE MunkaRendelesek
(munka_id INTEGER NOT NULL,
szakismeret_csoport INTEGER NOT NULL,
szakismeret_kod CHAR(15) NOT NULL,
PRIMARY KEY (munka_id, szakismeret_csoport, szakismeret_kod));
A szakismeret_csoport kd azt jelenti, hogy ezen szakismeretek mindegyike
szksges a munka elvgzshez - ezek az AND mvelettel sszekapcsolt kifejez
sek a kanonikus formban. Ezutn felttelezhetjk, hogy a munkarendelshez tar
toz sszes szakismeret_csoport az OR mvelettel kapcsoland ssze adott
munka_id esetn. Hozzuk ltre a tblt a munkarendelsek szmra, majd vegyk
fel az albbi rendelseket a kanonikus formjukban:
Munka 1 = ('raktrozs' AND 'gyrts') OR 'knyvels'
Munka 2 = ('raktrozs' AND 'gyrts')
OR ('knyvels' AND 'gyrts')
Munka 3 = 'gyrts'
Munka 4 = ('raktrozs' AND 'gyrts' AND 'knyvels')
Ez az albbi adatokat eredmnyezi a tblban:
INSERT ((1,
INTO
VALUES
(1,
(1,
(2,
(2,
(2,
(2,
(3,
(4,
(4,
(4,
MunkaRendelesek
1, 'raktrozs')
1, 'gyrts'),
2, 'knyvels'),
1, raktrozs'),
1, 'gyrts'),
2, 'knyvels ' ) ,
2, 'gyrts'),
1, 'gyrts'),
1, 'raktrozs'),
1, 'gyrts ' ),
1, 'knyvels')) ;
1
3. fejezet Adatkivlaszts
munkid
1
1
1
1
2
2
2
3
3
3
3
4
100
200
400
500
100
400
500
100
300
400
500
100
57
58
SQL-fejtrk
3. megolds
Egy msfajta megolds rkezett a Smith Barney alkalmazsban ll Richrd
Romley-tl. Olyan vlasszal llt el, ami nem jr az SQL-92-ben meglv kapcsolt
allekrdezs (korrellt allekrdezs) hasznlatval:
SELECT Jl.munka_id, Cl.jelolt_id
FROM (SELECT munka_id, szakism_csop, COUNT(*)
FROM MunkaSzakismlgenyek
GROUP B Y munka_id, szakism_csop)
AS Jl(munka_id, szakism_csop, csop_szam)
CROSS JIN
(SELECT Rl.munka_id, Rl.szakism_csop, Sl.jelolt_id. COUNT(*)
FROM MunkaSzakismlgenyek AS Rl, JeloltSzakismeretek AS Sl
WHERE Rl.szakismeret_id = Sl.szakismeret_id
GROUP B Y Rl.munka_id, Rl.szakism_csop, Sl.jelolt_id)
AS Cl(munka_id, szakism_csop, jelolt_id, jelolt_szam)
WHERE Jl.munka_id = Cl.munka_id
AND Jl.szakism_csop = Cl.szakism_csop
AND Jl.csop_szam = Cl.jelolt_szam
GROUP B Y Jl.munka_id, Cl.jelolt_id;
3. fejezet Adatkivlaszts
gyfelek
nev
cm
id
'Lajos'
'Jnos'
'Mrk'
'Mari'
Viktor'
'Pter'
A'B'
'C
'A*
'B'
'D'
csald
XLLL
NULL
NULL
1
NULL
3
5
1. megolds
Az els ksrlet nem sokkal tbb, mint a szveges feladatlers kzvetlen talakt
sa SQL kdd:
D E L E T E F R O M gyfelek
F R O M gyfelek A S Cl
2. megolds
Ha belegondolunk, hamar rjvnk, hogy a C O U N T (*) fggvny egy adott hztar
tsra 1-nl nagyobb rtket kell hogy adjon.
D E L E T E F R O M gyfelek
(SELECT
COUNT(*)
F R O M gyfelek A S Cl
W H E R E Cl.cim = cim) > 1;
59
60
SQL-fejtrk
ertekesito
'Katalin'
'Zsfia'
'Lajos'
'Lajos'
'Lajos'
'Evelin'
'Attila'
'Ferenc'
'Henrik'
'Tams'
'Mt'
'Zoltn'
'Jlia'
'Barbara'
'Mria'
'Adrienn'
'Szilvia'
ertekesitesid
5
11
1
2
3
4
8
7
6
7
10
9
15
16
12
14
13
sszeg
3.00
4.00
50.00
50.00
50.00
5.00
5.00
5.00
5.00
5.00
5.00
7.00
20.00
10.00
50.00
30.00
40.00
3. fejezet Adatkivlaszts
Megolds
Sajnos a feladatmeghatrozs nhny helyen homlyos. A hrom legnagyobb rt
kestsre van szksgnk (fggetlenl attl, hogy ki ttte nylbe az zletet) vagy
a hrom legjobb rtkestre? Klnbsg van ugyanis az eredmnyben: pldul ha
az l-es krzetet vizsgljuk, Lajos lesz a hrom legnagyobb rtkests, de a hrom
legjobb rtkest Lajos, Evelin s Zsfia.
Mi a helyzet akkor, ha hromnl tbb rtkest pontosan ugyanakkora zletet k
ttt, mint a 2-es krzetben? Ha egy krzetben hromnl kevesebb rtkest dolgo
zik, ahogy a 3. krzet esetben, hagyjuk-e ki ket a jelentsbl, vagy sem? Elszr
vegyk gy, hogy a fnk a hrom legnagyobb rtkestsre kvncsi, az rtkest
szemlytl fggetlenl. A lekrdezs ebben az esetben az albbi formt ltheti:
SELECT *
FROM ErtekesitesiAdatok AS SO
WHERE sszeg IN (SELECT sszeg
FROM ErtekesitesiAdatok AS Sl
WHERE SO.krzet = Sl.krzet
AND SO.sszeg <= Sl.sszeg
HAVING COUNT(*) <= 3)
ORDER BY krzet, ertekesito, ertekesites_id, sszeg;
ertekesito
'Lajos'
'Lajos'
'Lajos'
'Mt'
'Zoltn'
'Mria'
'Adrienn'
'Szilvia'
ertekesitesjd
1
2
3
10
9
12
14
13
sszeg
50.00
50.00
50.00
5.00
7.00
50.00
30.00
40.00
61
62
SQL-fejtrk
ertekesito
'Zsfia'
'Evelin'
'Lajos'
Attila'
'Ferenc'
'Henrik'
'Tams'
'Mt'
'Zoltn'
'Adrienn'
'Szilvia'
'Mria'
3. fejezet Adatkivlaszts
1. megolds
n a legkzenfekvbb megoldst vlasztottam:
SELECT sorszm
FROM TesztEredmenyek AS
WHERE NOT EXISTS (SELECT
FROM
WHERE
AND
TI
*
TesztEredmenyek AS T2
TI.sorszm = T2.sorszm
T2.telj_datum IS NULL);
2. megolds
Roy Harvey egy jobb s egyszerbb megoldst mutatott, amely teljesen mskpp
kzeltette meg a problmt:
SELECT
FROM
GROUP
HAVING
sorszm
TesztEredmenyek
BY sorszm
COUNT(*) = COUNT(telj_datum);
SQL-fejtrk
Ez is mkdik, hiszen a COUNT (*) a NULL rtk tel j_datum mezket is megsz
molja (hiszen valjban teljes sorokat szmol), mg a COUNT (tel j_datum) az
sszegzs eltt eldobja a NULL rtkeket. Ez egy jl hasznlhat fogs, amikor kt
halmazt kell sszehasonltanunk.
1. megolds
A hagyomnyos vlasz a krdsre az, hogy levesszk a polcrl valamelyik tan
knyvet s fellapozzuk a relcis osztst. Chris Date, az egyik klasszikus szerz,
knyvnek tdik kiadsban egy olyan pldt kzl, amelyrl lemsolhatjuk
a megoldst. Elosztjuk a piltk kpestst trol tblt (osztand) a hangr tbl
jval (oszt), gy megkapjuk a keresett piltk neveinek listjt (hnyados).
2. megolds
Vessnk egy pillantst a kzvetlenl ezeltti feladvnyra. A Teszteredmnyek prob
lmjra alkalmazott Roy Harvey-fle fogs ebben az esetben is hasznlhat. Fon
tos, hogy a korbban tanult trkkket j problmk esetn is alkalmazni tudjuk!
Kpzeljk el, hogy minden pilta kap egy csomag matrict, amit azoknak a hangr
ban lv gpeknek az oldalra ragaszthat, amelyek vezetsre kpes. Ha a hangr
ban ll replgpek szma megegyezik a pilta ltal felhasznlt matrick szm
val, akkor a pilta minden gpet vezethet. Ez alapjn a lekrdezs az albbi:
SELECT
FROM
WHERE
GROUP
HAVING
Pilta
PilotaKepzettseg AS PS1, Hangr AS Hl
PS1.replgp = Hl.replgp
BY PS1.pilta
COUNT(PS1.replgp) = (SELECT COUNT(*) FROM Hangr);
3. fejezet Adatkivlaszts
F R O M Brlemnyek AS Ul
LEFT O U T E R JIN
(Berlok AS T I
LEFT O U T E R JIN
Djfizetsek AS RP1
ON TI.berlo_azon = RPl.berlo_azon)
ON Ul.brlemny_azon = TI.brlemny_azon
WHERE Ul.komplexum_azon = 32
AND Ul.brlemny_azon = RP1.berlemeny_azon
AND TI.tvozott I S NULL
AND ((RP1.fizdatum >= :vizsg_datum
AND RPl.fizdatum < :vizsg_datum)
OR RPl.fizdatum IS NULL)
ORDER BY Ul.berlemeny_szam, RPl.fizdatum;
SQL-fejtrk
Megolds
Gondoljunk arra, hogy mi az lland s mi a vltoz rsz az O U T E R J I N kapcsola
tokban. A brlemny-brl prokbl kell kiindulnunk: a brlemnyek mindig
ugyanazok, de a brlk jnnek-mennek, gy meg kell riznnk a LEFT O U T E R J I N
kapcsolat brlemny felli oldalt. Ha megvannak a brlemny-brl prjaink, te
gyk fel mg egyszer ugyanezt a krdst. Megllapthatjuk, hogy a djfizetsek is
jhetnek s mehetnek, mg akkor is, ha a brlemnyt valaki ppen brli.
SELECT *
FROM (Brlemnyek AS Ul
LEFT OUTER JIN Berlok AS T I
O N Ul.brlemny_azon = Tl.brlemny_azon
AND Tl.tvozott IS NULL
AND Ul.komplexum_azon = 32)
LEFT OUTER JIN Djfizetsek AS RPl
O N (Tl.berlo_azon = RPl.berlo_azon
AND Ul.berlemeny_azon = RPl.brlemny_azon)
WHERE ((RPl.fizdatum >= :vizsg_datum
AND RPl.fizdatum < :vizsg_datum)
OR RPl.fizdatum IS NULL)
ORDER BY Ul.berlemeny_szam. RPl.fizdatum;
A (Tl.berlo_azon = RPl.berlo_azon AND Ul.brlemny_azon =
RPl.brlemny_azon) felttel azt jelenti, hogy egy bizonyos brl fizetett mr
egy bizonyos brlemnyrt. Ez azokat az eseteket fedi le, amikor ugyanaz a trsa
sg a komplexum egynl tbb brlemnyt veszi brbe. Felttelezhetjk, hogy
a hivatkozsi megszortsok megvnak attl, hogy olyasvalakitl szedjnk be br
leti djat, aki nem rendelkezik egy brlemnnyel sem.
3. fejezet Adatkivlaszts
1. megolds
sszekapcsolva a hrom tblt hozzunk ltre egy nzettblt, gy megkapjuk azo
kat az alapvet informcikat, amik utn kutatunk. Taln ksbb mg jl jn majd
ez a nzettbla egyb jelentsek ksztsekor.
CREATE VIEW Magazinok(stand_nev, cim, net_eladott_menny)
AS SELECT Eladsok.stand_nev, Cimek.cim, net_eladott_menny
FROM Cimek, Eladsok, Ujsagosstandok
WHERE Eladsok.stand_szam = Ujsagosstandok.stand_szam
AND Cimek.termek_id = Eladsok.termek_id;
SQL-fejtrk
2. megolds
1995 prilisban Carl C. Federl, az Illinois llamban fekv Clarendon Hillsben l
fggetlen szakrt vetette fel, hogy a feladvnyra adott vlasz kt fogs alkalmaz
sval nagymrtkben leegyszersthet. Elszr egy nzettblt hoz ltre az elad
sok tlagnak szmra, majd egy EXISTS () fggvnyt vesz fel a felttelhez, amely
ben mindkt cmnek meg kell haladnia egy kszbrtket.
CREATE VIEW Magazinok (stand_szam, cim, atl_elad_menny)
AS SELECT Eladsok.stand_szam, Cimek.cim,
AVG(Eladsok.net_eladott_menny)
FROM Cimek, Ujsagosstandok, Eladsok
3. fejezet Adatkivlaszts
WHERE
AND
AND
GROUP
Cimek.termek_id = Eladsok.termek_id
Ujsagosstandok.stand_szam = Eladsok.stand_szam
Cimek.cim IN (01107, 02667, 48632)
BY Eladsok.stand_szam, Cimek.cim;
69
70
SQL-fejtrk
a rekordokat jelenten meg, ahol pontosan egy nem NULL elem van az oszlopok
rtkei kztt. Vajon hny klnbz elvre pl megoldst tudunk sszelltani?
Most a vltozatossgot s nem a teljestmnyt lltjuk a kzppontba.
1. megolds
A Sybase s ms hasonl SQL-ek hasznlata esetn alkalmazhatjuk a SIGN () fgg
vnyt. A fggvny a -1, 0 vagy +1 rtkekkel tr vissza, ha a paramterknt tadott
rtk negatv, nulla vagy pozitv (ebben a sorrendben). Felttelezve, hogy a szma
ink nullk vagy annl nagyobbak, egyszeren rhatjuk a kvetkezt:
SELECT *
FROM Tbla
WHERE SIGN(fl) + SIGN(f2) + ... + SIGN(flO) = 1;
2. megolds
Mivel a mezkkel valban egy tmbt helyettestettek, normalizlnunk kell ezt
a tblt az INF (els normlforma) szerint:
CREATE TABLE Akrmi
(kulcsmezo INTEGER NOT NULL,
i INTEGER NOT NULL CHECK (i BETWEEN 1 AND 10),
f INTEGER NOT NULL,
PRIMARY KEY (kulcsmezo, i));
Az i nven hozzadott oszlop a tmb indexe. Most mr tekinthetnk gy a krds
re, mint annak az egyednek a megkeressre, amelyik pontosan kilenc nulla rtk
f-kkel rendelkezik, ahelyett, hogy azokat kutatnnk, amelyek pontosan egy nem
nulla f-rtkkel brnak. Ez igen egyszer:
3. fejezet Adatkivlaszts
SELECT
FROM
WHERE
GROUP
HAVING
kulcsmezo
Akrmi
f =0
BY kulcsmezo
COUNT(*) = 9;
3. megolds
Ennek a megoldsnak a mkdse az SQL-92 egy olyan tulajdonsgra pl, ami
nek az elrhetsge manapsg mg nem ltalnosan biztostott. Nzzk elszr
a kdot, utna a magyarzatot:
SELECT *
FROM Tbla
WHERE (fl, f2, ... , flO) IN
((fl, 0, 0, 0, 0, 0, 0, 0, 0, 0 ) ,
(0, f2, 0, 0, 0, 0, 0. 0, 0, 0 ) ,
(0, 0, 0, 0, 0, 0, 0, 0, 0, flO));,
Az SQL-92-ben a feltteles lltsokban hasznlhatunk sorltrehoz fggvnyeket.
Az IN () prediktum a kifejezst OR mvelettel sszekapcsolt egyenlsgi feltte
lekk bontja ki. Az egyenlsg sormegfelel vltozata ezutn pozcinknt haladva
hajtja vgre az ellenrzst, amelynek sorn minden megfelel rtknek egyenlnek
kell lennie.
71
72
SQL-fejtrk
4. megolds
Ha kizrlag egy mez lehet nem nulla, akkor ez annyit jelent, hogy lteznie kell
a mezk olyan kilences csoportjnak, amelyben minden rtk nulla.
SELECT
FROM
WHERE
OR
*
Tbla
(f2 + f3 + .. flO) = 0 -- az fl-et kivve
(fl + f3 + .. flO) = 0 -- az f2-t kivve
(1-elfogadva )
(2-teljestve')
(3='visszaigazolva')
73
3. fejezet Adatkivlaszts
rendels
4155526710
4155526710
4155526710
4155526711
4155526711
4155526711
men_sor
1
2
3
1
2
3
szolgtip
ul
01
01
01
01
01
men_akt_daturn
'1994-07-16'
'1994-07-30'
'1994-10-01'
'1994-07-16'
'1994-07-30'
NULL
elfogadva
'1994-07-16'
'1994-07-16'
teljestve
'1994-07-16'
'1994-07-16'
visszaigazolva
'1994-10-01'
NULL
1. megolds
Az SQL-92-ben a megolds bels lekrdezsek hasznlatval egyszer s gyors:
SELECT rendels,
(SELECT men_akt_datum
FROM Menetrend AS Sl
WHERE Sl.men_sor = 1
AND Sl.rendels = SO.rendels) AS elfogadva,
(SELECT men_akt_datum
FROM Menetrend AS S2
WHERE S2.men_sor = 2
AND S2.rendels = SO.rendels) AS teljestve,
(SELECT men_akt_datum
FROM Menetrend AS S3
WHERE S3.men_sor = 3
AND S3.rendels = SO.rendels) AS visszaigazolva
FROM Menetrend AS SO
WHERE szolg_tip = :vizsg_szolg_tip; -- a szolg. tpus belltsa
Az j fogsokkal az a baj, hogy a hasznlt SQL-ben esetleg nem optimalizlhatk.
SQL-fejtrk
2. megolds
Egy msik megkzelts n-sszekapcsolsokat alkalmaz, ami az SQL-89 s SQL-92
szerint egyarnt mkdik.
SELECT SO.rendels.men_akt_datum, SO.men_akt_datum,
Sl.men_akt_datum, S2.men_akt_datum, S3.men_akt_datum
FROM Menetrend AS SO, Menetrend AS Sl,
Menetrend AS S2, Menetrend AS S3
WHERE SO.szolg_tip = :vizsg_szolg_tip -- a szolg. tpus belltsa
AND SO.rendels = :vizsg_rendeles -- a rendels belltsa
AND Sl.rendels = SO.rendels AND Sl.men_sor = 1
AND S2.rendels = SO.rendels AND S2.men_sor = 2
AND S3.rendels = SO.rendels AND S3.men_sor = 3;
3. megolds
Esetleg megprblhatjuk UNlON-ok s egy munkatbla hasznlatval ktdimenzis
s (fiat table) alaktani az eredeti tblt. Ennek teljestmnye rendszerint nem tl j,
de ha az eredeti tbla nagyon nagy, nha gyorsabb lehet a 2. megoldsnl.
INSERT INTO Munka (rendels, elfogadva, teljestve, visszaigazolva)
SELECT rendels, NULL, NULL, NULL
FROM Menetrend AS SO
WHERE szolg_tip = :vizsg__rendeles -- a szolg. tpus belltsa
UNION
SELECT rendels, men_akt_datum, NULL, NULL
FROM Menetrend AS Sl
WHERE Sl.men_sor = 1
AND Sl.rendels = :vizsg_rendeles
AND szolg_tip = :vizsg_szolg_tip -- a szolg. tpus belltsa
UNION
SELECT rendels, NULL, men_akt_datum, NULL
FROM Menetrend AS S2
WHERE S2.men_sor = 2
AND S2.rendels = :vizsg_rendeles
AND szolg_tip = :vizsg_szolg_tip -- a szolg. tpus belltsa
3. fejezet Adatkivlaszts
UNION
SELECT rendels, NULL, NULL, men_akt_datum
FROM Menetrend AS S3
WHERE S3.men_sor = 3
AND S3.rendels = :vizsg_rendeles
AND szolg_tip = :vizsg_szolg_tip -- a szolg. tpus belltsa
A MAX () fggvny a csoport legnagyobb nem NULL rtkt veszi ki, ami ugyanak
kor az egyetlen nem NULL rtk a csoportban.
AFD
diagram
alakzat
Lolyl
bemenet
Folyl
Folyl
bemenet
dnts
adataram
becslsek
vlemnyek
tnyek
75
76
SQL-fejtrk
diagram
lolyl
Folyl
Folyl
Folyl
Foly2
Foly2
alakzat
dnts
dnts
kimenet
kimenet
szmts
szmts
adataram
becslsek
vlemnyek
tnyek
becslsek
becslsek
vlemnyek
1. megolds
Hasznlhatnnk a kvetkez SQL-92 lekrdezst:
SELECT FI.diagram, FI.alakzat, F2.adataram
FROM (SELECT Fl.diagram, FI.alakzat FROM AFD AS FI
CROSS JIN
SELECT DISTINCT F2.adataram FROM AFD AS F2)
EXCEPT
SELECT F3.diagram, F3.alakzat, F3.adataram FROM AFD AS F3
ORDER BY Fl.diagram, Fl.alakzat, F2.adataram;
A mkds lnyege, hogy ellltjuk a diagramok s adatramok sszes lehetsges
kombincijt, majd eltvoltjuk azokat, amelyek szerepelnek a tblban. A rossz
hr az, hogy a mai SQL-termkek tbbsgben ezt valsznleg csak nzettblk
segtsgvel valsthatjuk meg.
3. fejezet Adatkivlaszts
2. megolds
Egy msik SQL-92 lekrdezs lehetne az albbi:
SELECT FI.diagram, FI.alakzat, F2.adataram
FROM (SELECT Fl.diagram, Fl.alakzat FROM AFD AS FI),
CROSS JIN
(SELECT DISTINCT F2.adataram
FROM AFD AS F2
WHERE adataram NOT IN (SELECT F3.adataram
FROM AFD AS F3
WHERE F3.diagram
Fl.diagram
AND F3.alakzat
Fl.alakzat))
ORDER BY Fl.diagram, Fl.alakzat, F2.adataram;
3. megolds
Ha az SQL-89 szerint szeretnnk a vlaszt megrni, akkor nzettblk hasznlatra
lesz szksgnk:
-- az sszes adatram ellltsa
CREATE VIEW MindenAFDAram (adataram)
AS SELECT DISTINCT adataram FROM AFD;
-- az egyes adatramok hozzrendelse az eredeti tbla soraihoz
CREATE VIEW Uj AFD (diagram, alakzat, adataram, hianyzo_adataram)
SELECT DISTINCT Fl.diagram, Fl.alakzat, Fl.adataram, F2.adataram
FROM AFD AS Fl, MindenAFDAram AS F2
WHERE Fl.adataram <> F2.adataram;
-- Lssuk az egyes (diagram, alakzat) prokat s a hinyz
-- adatramokat, ahol a hinyz adatram nem felel meg
-- a prhoz tartoz egyik adatramnak sem
SELECT DISTINCT diagram, alakzat, hianyzo_adataram
FROM UjAFD AS ND1
WHERE NOT EXISTS (SELECT *
FROM UjAFD AS ND2
WHERE ND1.diagram = ND2.diagram
AND ND1.alakzat = ND2.alakzat
AND ND1.adataram = ND2.hianyzo_adataram)
ORDER BY diagram, alakzat, hianyzo_adataram;
77
SQL-fejtrk
3. fejezet Adatkivlaszts
1. megolds
Az egyik megkzeltsi md egy F U L L O U T E R J I N hasznlata lenne minden egyes
beszlltpron. gy elkerlne minden olyan alkatrsz, ami nincs mindketthz
rendelve, de soronknt az I N N E R J I N kapcsolatban nem szerepl beszllttl
szrmazan egy N U L L is megjelenne valamelyik oszlopban. Ezzel megtudjuk, mely
prok nem illeszkednek, de hogy melyik rszrl, azt nem. A befejez lps ezen
nem illeszked prok eltvoltsa az sszes lehetsges pr kzl.
S E L E C T SP1.Beszall_id, SP2.Beszall_id
FROM BeszallitoAlkatresz AS SP1
INNER JIN
BeszallitoAlkatresz AS SP2
EXCEPT
(SELECT DISTINCT SP1.Beszall_id, SP2.Beszall_id
FROM BeszallitoAlkatresz AS SP1
FULL OUTER JIN
BeszallitoAlkatresz AS SP2
ON SP1.alkatresz_id = SP2.alkatresz_id
AND SP1.Beszall_id < SP2.Beszall_id)
WNERE SP1.Beszall_id IS NULL
OR SP2.Beszall_id IS NULL;
2. megolds
Kt halmaz egyenlsgt gy szoks bizonytani, hogy megmutatjuk, hogy az
A halmaz tartalmazza B-t, ugyanakkor a B halmaz is tartalmazza az A-t (A c B A B
c A) > (A = B). A szabvnyos SQL-ben az lltst, hogy A rszhalmaza B-nek,
rendszerint azzal a mdszerrel ltjuk be, hogy az A halmaznak nincs olyan eleme,
ami a B-nek nem az eleme. gy az els prblkozs ltalban valami ilyesmi:
79
SQL-fejtrk
3. megolds
A 2. megoldsban vzolt hagyomnyos teszt megvalstsra hasznlhatjuk az ALL
felttelt:
SELECT SPl.Beszall_id, SP2.Beszall_id
FROM BeszallitoAlkatresz AS SPl. BeszallitoAlkatresz AS SP2
WHERE SPl.Beszall_id < SP2.Beszall_id
AND NOT EXISTS (SELECT *
FROM BeszallitoAlkatresz AS SP3
WHERE SPl.Beszall_id = SP3.Beszall_id
AND SPl.alkatresz_id
NOT IN (SELECT alkatresz_id
FROM BeszallitoAlkatresz AS SP4
WHERE SP2.Beszall_id =
SP4.Beszall_id))
AND NOT EXISTS (SELECT *
FROM BeszallitoAlkatresz AS SP5
WHERE SP2.Beszall_id = SP5.Beszall_id
AND SP2.alkatresz_id
NOT IN (SELECT alkatresz_id
FROM BeszallitoAlkatresz AS SP4
WHERE SPl.Beszall_id =
SP4.Beszall_id));
3. fejezet Adatkivlaszts
4. megolds
A halmazok egyezsgi vizsglatnak hagyomnyos mdja: elszr sszekapcsol
juk a kt beszlltt a kzs rszk alapjn, kikszblve azt a helyzetet, amikor az
1. beszllt megegyezik a 2. beszlltval, gy megkapjuk a kt halmaz metszett.
Ha a metszet pontosan annyi szm prt tartalmaz, mint brmelyik halmaz elem
szma, akkor a kt halmaz egyenl.
SELECT SPl.Beszall_id, SP2.Beszall_id
FROM (SELECT Beszall_id, alkatresz_id FROM BeszallitoAlkatresz)
AS SP1
INNER JIN
(SELECT Beszall_id, alkatresz_id FROM BeszallitoAlkatresz
AS SP2
ON SP1.alkatresz_id = SP2.alkatresz_id
AND SP1.Beszall_id < SP2.Beszall_id)
GROUP BY SP1.Beszall_id, SP2.Beszall_id
HAVING (SELECT COUNT(*)
FROM BeszallitoAlkatresz AS SP3
WHERE SP3.Beszall_id = SP1.Beszall_id)
= (SELECT COUNT(*)
FROM BeszallitoAlkatresz AS SP4
WHERE SP4.Beszall_id = SP2.Beszall_id);
81
Szmtsok.
Az SQL nem tartozik a szmtsi nyelvek kz. Az ANSI/ISO szerinti szabvnyos
SQL-92 csak 4 szmtsi mveletet tesz lehetv, s ezzel gyengbb teljestmnyt
nyjt, mint egy j minsg szmolgpes karra. A legtbb szoftvercg azonban
az SQL-termkeibe is bept ms fordtprogramokban megszokott fggvny
knyvtrakat, gy szksg esetn rendelkezsnkre ll a szmtsi kpessg. A je
lenlegi ANSI/ISO SQL3 ajnlsok tbb eljrst hatroznak meg a nyelv szmra.
A fejlesztk szmra nyitott a lehetsg, hogy termkeikben megvalstsk az
SQL3 ajnlsait mr azeltt is, hogy a szabvny rvnybe lpne.
A fggvnyek, amelyeket az SQL-ben sajt magunknak kell megrnunk, sszegz
s skalris fggvnyek lehetnek.
Az alapvet skalris fggvnyek - mint amilyen a szinusz vagy a koszinusz - meg
valstsnak egyik egyszer mdja egy tbla ltrehozsa, majd ebben egy keress
az adott rtkre. Ennl fantziadsabb megoldst egy kzelt rtket szmt le
krdezs vagy nzettbla jelenthet.
A bonyolultabb fggvnyek megvalstsa rendszerint tbb tblbl val rtkki
keresssel s ezeket felhasznlva tovbbi szmtsokkal jr.
84
SQL-fejtrk
1. megolds
Egyszeren hozzunk ltre egy tblt, ami az sszes szksges rtket tartalmazza:
CREATE TABLE Szinusz
(x REL NOT NULL,
sin REAL NOT NULL);
INSERT INTO Szinusz VALUES (0.00, 0.0000);
INSERT INTO Szinusz VALUES (0.75 0.6816);
INSERT INTO Szinusz VALUES (0.76 0.6889);
stb.
A tbla feltltshez egy tblzatkezel programot clszer ignybe venni. Ezutn
mr hasznlhatjuk is az albbi bels lekrdezst a sin (: vizsgalt_ertek) kisz
mtsra:
(SELECT sin FROM Szinusz WHERE x = :vizsgalt_ertek)
Termszetesen egyes fggvnyek megvalstshoz igen nagy tblkra lenne szk
sgnk, de kisebb, korltozott tartomnyon rtelmezett fggvnyeknl j lehet ez
a megkzelts. A szinusz fggvnynl ppensggel rettenetes vlaszts, mivel egy
folytonos, minden vals szmon rtelmezett fggvnyrl van sz.
2. megolds
szrevettk, hogy ha a : vizsgalt_ertek nem szerepel az els megoldsban meg
adott tblban, akkor a lekrdezs N U L L rtket ad vissza? Ez gy nem j.
4. fejezet Szmtsok
85
86
SQL-fejtrk
1. megolds
Az SQL-89-ben a legjobb megolds taln az, ha elszr egy nzettblt hozunk ltre:
CREATE VIEW KeresetSzamok
A S SELECT COUNT(*) A S fiz_utalvany_szam
FROM Fiz_jegyz
GROUP BY kereset;
Ezutn ennek a nzettblnak a hasznlatval megkeressk a leggyakrabban el
fordul fizetssszeget:
SELECT kereset, COUNT (*)
FROM Fiz_jegyz
GROUP BY kereset
HAVING COUNT (*) = (SELECT MAX(fiz_utalvany_szam)
FROM KeresetSzamok);
Ezzel a megoldssal azonban egy nzettblt vagyunk knytelenek az adatbzisban
trolni. Ha erre ms okbl is szksgnk van, akkor a hasznlata knyelmes, ellen
kez esetben viszont feleslegesen bonyoltja az adatbzist. Jobb lenne, ha V T E W
nlkl, egy lekrdezssel megoldhat lenne ugyanez.
87
4. fejezet Szmtsok
2. megolds
Az SQL-92 lehetv teszi, hogy a nzettblt egy tblzatos bels lekrdezss ala
ktsuk t:
S E L E C T kereset,
COUNT(*)
F R O M Fiz_jegyz
G R O U P B Y kereset
HAVING
COUNT(*)
( S E L E C T MAX(fiz_utalvany_szam)
FROM
(SELECT COUNT(*)
A S fiz_utalvany_szam
F R O M Fiz_jegyz
G R O U P B Y kereset));
3. megolds
me egy jabb SQL-92 megolds, ami kicsit mskpp kezeli a N U L L rtkeket. Meg
tudjuk llaptani, mi a klnbsg?
SELECT
PO.kereset,
COUNT(*)
F R O M Fiz_Jegyz
G R O U P B Y kereset
HAVING
COUNT(*)
>= A L L (SELECT
COUNT(*)
F R O M Fiz_jegyz
G R O U P B Y kereset);
88
SQL-fejtrk
vasariasdatum
'1994-06-01'
'1994-06-01'
'1994-06-01'
'1994-06-02'
1994-06-02'
'1994-06-03'
'1994-06-04'
'1994-06-08'
'1994-06-06'
'1994-06-07'
'1994-06-07'
'1994-06-08'
Az adatokbl az ltszik, hogy Feri elszr egy napot vrt, majd a kvetkez vsr
lsig tt, gy addik szmra az tlagos hromnaponknti ltogats. Mari ht na
pot vrt kt vsrls kztt, ez htnapos tlagot jelent, Zoli pedig szablyosan, na
ponta teszi tisztelett.
4. fejezet Szmtsok
1. megolds
Az els sugallat, hogy ltre kellene hozni valamikppen egy rszletes nzettblt,
amely minden gyfl esetn sorban mutatja a beszerzsek kzt eltelt idt. Ebben
a megkzeltsben az els feladat, hogy egy tblba gyjtsk ssze az aktulis s
a megelz vsrlsok dtumait:
CREATE VIEW Utolso_vasarlasok (ugyfel, ez_a_datum, utolso_datum)
AS SELECT Sl.ugyfel, Sl.vasrlas_datum,
(SELECT MAX(vasarlas_datum)
FROM Vsrls AS S2
WHERE S2.vasarlas_datum < Sl.vasarlas_datum
AND S2.ugyfel = Sl.ugyfel)
FROM Vsrls AS Sl, Vsrls AS S2;
Ez a kisebbek fels hatrt keres lekrdezs: az adott gyflhez tartoz, a vizsglt
dtumnl korbbi legnagyobb dtumot keressk.
Most egy nzettblt hozunk ltre az aktulis s a megelz vsrlsok kzt eltelt
napok szmval. Egyetlen utastsban is megvalsthatnnk a kt nzettblt, de
gy nehezen olvashatv vlna s valsznleg a futtats szempontjbl sem jelen
tene hatkonyabb megoldst.
CREATE VIEW Idokoz (ugyfel, napok)
AS SELECT ugyfel, DAYS(ez_a_datum, utolso_datum)
FROM Utolso_vasarlasok;
89
90
SQL-fejtrk
2. megolds
Azrt mutattam be az els megoldst, hogy megmutassam: vannak olyan esetek,
amikor tl okosak vagyunk a feladathoz. Mivel csak az egyes gyfelek vsrlsai
kzt eltelt napok tlagra vagyunk kvncsiak, nincs szksg rszletes nzettbla
ltrehozsra. Egyszeren szmoljuk ssze gyfelenknt az sszes eltelt napot,
majd az sszeget osszuk el a vsrlsok szmval:
SELECT ugyfel, (MAX(vasarlas_datum) - MIN(vasarlas_datum)) /
(COUNT(*)-l)
FROM Vsrls
GROUP BY ugyfel
HAVING COUNT(*) > 1;
A (COUNT (*) -1) kifejezs magyarzata, hogy mindig egyel kevesebb a vsrlsok
kzti idszakok szma, mint a vsrlsok, ha nem szmtjuk a mai dtum s az
utols vsrls kzti idszakot. A HAVING zradk eltvoltja az egyetlen vsrlssal
br gyfeleket. Ezek az egyszeri gyfelek is bevonhatk a SELECT utastsba, ha
a MAX (vasarlas_datum) kifejezst CURRENT_DATE fggvnyre cserljk.
Egybknt mindkt megkzeltssel kezelhetjk a napi tbb vsrlst nylbe t
gyfeleket is.
4. fejezet Szmtsok
1. megolds
A hagyomnyos megolds egy sokszorosan begyazott lekrdezs. A lekrdezst
gy lehetne htkznapi nyelvre lefordtani: Hatrozzuk meg azoknak az gyfelek
nek az tlagegyenlegt, akik esetben ltezik olyan termk, amely nem szerepel
a rendelseik kztt!".
SELECT AVG(egyenleg)
FROM gyfelek AS Cl
WHERE EXISTS
(SELECT *
FROM Termkek AS Pl
WHERE Pl.tetei
NOT IN (SELECT Dl.tetei
FROM Rendelesek AS 01, Rend_tetelek AS Dl
WHERE 01.ugyfel_id = Cl.ugyfel_id
AND 01.ugyfel_id = Dl.ugyfel_id));
91
92
SQL-fejtrk
EXISTS
() felttelt N O T
2. megolds
Az angliai Worcestershire-ben l Gillian Robertson egy gyes trkkel megtakar
totta az sszefgg bels lekrdezsek nhny rtegt.
SELECT AVG(egyenleg)
FROM gyfelek AS Cl
WHERE (SELECT COUNT(DISTINCT tetel_id) FROM Termkek)
<> (SELECT COUNT(DISTINCT tetel_id)
FROM Rendelesek, Rend_tetelek
WHERE Rendelesek.ugyfel_id = Cl.ugyfel_id);
Ez a lekrdezs kiszmtja azoknak az gyfeleknek az tlagos egyenlegt, akik nem
vsroltak minden termkbl, biztostva azt a felttelt, hogy az gyfelek ltal vs
rolt klnbz termkek szma nem egyezik meg a termktblban lv klnb
z termkek szmval. Nyilvnval, hogy a <> egyenlsgjelre val cserjvel azo
kat az gyfeleket kapjuk meg, akik minden forgalmazott termkbl rendeltek mr.
4. fejezet Szmtsok
Egy olyan rendszerrl van sz, amelyben minden adkrzet fizeti a megfelel ad
kat azoknak az adhatsgoknak, amelyek krzetbe beleesik:
AdoKorzetHatosag
adhatsg
adokorzet
'vrosi' 'vrosi'
'varos2' 'varos2'
Varos3'
'megyei'
'megyei'
'megye2'
'llami'
'llami'
'llami'
Varos3'
'vrosi'
'varos2'
'varos3'
'vrosi'
'varos2'
'varos3'
hatlybalps
'1993-01-01'
'1994-01-01'
'1993-09-01'
'1994-01-01'
'1995-01-01'
'1993-01-01'
'1993-07-01'
'1993-01-01'
'1994-10-01'
hat^adomertek
1,0
1,5
1,5
2,0
2,5
1,7
1,9
2,3
2,5
93
94
SQL-fejtrk
adhatsg
'megyei'
'megye2'
'megye2'
'megye2'
'llami'
'llami'
'llami'
'llami'
hatlybalps
'1995-ui-or
'1993-01-01'
'1994-01-01'
'1995-01-01'
1993-01-01'
'1994-07-01'
'1994-07-01'
'1994-10-01'
hatadomertek
2,7
2,4
2,7
2,8
0,5
0,8
0,9
1,1
= 2,0
= 2,5
=1,1
Teljes admrtk:
= 5,6
Megolds
A legjobb, ha rszletekben oldjuk meg a krdst. Elszr is azt kell tudnunk, hogy
milyen adhatsgok tartoznak a vroshoz, amit egy bels lekrdezssel kapha
tunk meg:
(SELECT adhatsg
FROM AdoKorzetHatosag AS Al
WHERE Al.adokorzet = ' v a r o s 2 ' )
4. fejezet Szmtsok
95
SQL-fejtrk
4. fejezet Szmtsok
Egy msik tblban az egyes gpek hasznlata kzben adott munkaegysg elvg
zsekor felmerl kltsgeket troljuk:
CREATE TABLE Gyrtsi_Ktg
(gep CHAR(20) NOT NULL REFERENCES Gpek,
munka_datum DATE NOT NULL,
folyamat INTEGER NOT NULL,
munka_ktg DECIMAL (6,2) NOT NULL,
PRIMARY KEY (gep, munka_datum, folyamat));
A munka_datum mez azt a dtumot trolja, amikor az adott munkafolyamat lezaj
lott a gpen, a munka_ktg pedig ennek a kltsgt. Egy hasonl tblban a terme
lsi idk arrl tjkoztatnak, hogy az egyes munkaegysgek vgrehajtshoz
mennyi idre van szksg. Ez a tbla a kvetkez mdon pl fel:
CREATE TABLE Gyartasi_Orak
(gep CHAR(20) NOT NULL REFERENCES Gpek,
munka_datum DATE NOT NULL,
folyamat INTEGER NOT NULL,
munkark DECIMAL(4,2) NOT NULL,
PRIMARY KEY (gep, munka_datum, folyamat));
A feladatunk, hogy egy clszerbb adatbzisszerkezetet javasoljunk az adatok tro
lsra. Ezutn lekrdezst kell rnunk, amely megadja egy tetszlegesen kivlasz
tott dtum s gp esetn a gp mkdtetsnek egy rra vettett tlagos kltsgt.
Megolds
Az eredeti adatbzisszerkezetben az id s a kltsgek adatait kln tblban trol
tuk, mivel az adatokat kln forrsbl kapta a rendszer, egyrszt blyegzkrtyk
rl, msrszt a szmlzsi osztlytl.
A termelsi kltsgeket (munka_ktg) s a szksges idt (munkark) egyetlen
tblban, sszevonva kellene trolni, amelyben a gp, a dtum s a munkafolya
mat szma alkotna kulcsot. Ha lehetnek olyan rk, amelyek kltsgei nem ismer
tek, vagy kltsgek, amelyekhez nem tartozik id, akkor ezekben az oszlopokban
engedlyezhetjk a N U L L rtkeket, de a matematikai mveletekre figyelni kell.
A kt tblt az albbival helyettestenm:
97
98
SQL-fejtrk
munkadatum
'1995-07-24'
'1995-07-25'
'1995-07-25'
'1995-07-26'
'1995-07-27'
'1995-07-27'
'1995-07-28'
folyamat
101
102
103
104
105
106
107
munkark
2,5
2,5
2,0
2,5
2,5
2,5
2,5
munkaktg
123,00
125,00
110,00
125,00
120,00
120,00
125,00
Jlius 24-n, a hasznlatba vtelt kvet els napon az tlagos mkdsi kltsg
((123,00 + 10,00)/2,5) = 127,00 dollr volt rnknt. Ellenben jlius 25-n, a haszn
lat msodik napjn, az tlagos kltsg rnknt mindssze (123,00 + 125,00 +
110,00 + (2*10,00))/(2,5 + 2,5 + 2,0) = 55,43 dollr, ami figyelemre mlt cskkens.
Az els 5 v vgn a gp zemeltetsi kltsge rnknt 52,82 dollrra cskkent.
Br ms megkzeltsi mddal is megkaphatnnk a helyes eredmnyt, n inkbb
nzettblt hozok ltre az sszes kltsg s id meghatrozsra, ez felhasznlhat
egyb napi jelentsek ksztshez is.
CREATE VIEW OsszOraKtg (gep, munka_datum, napi_ktg, napi_orak)
AS SELECT gep, munka_datum, SUM(munka_ktg), SUM(munkark)
FROM GyartasiOraKtg
GROUP BY gep, munka_datum;
Tegyk fel, hogy kt dtum kzt eltelt napok szma a kt DATE tpus vltoz rtk
bl kivonssal meghatrozhat. Ezzel a lekrdezs egyszeren az albbi alakot lti:
4. fejezet Szmtsok
SQL-fejtrk
3),
5),
2),
4));
Egyetlen lekrdezst szeretett volna, ami a nevek listja mellett feltntetn az egyes
munkkhoz tartoz sszes djat. A dj sszegt alkalmazottanknt llaptjuk meg,
a munkban tlttt id s a munka idpontjnak megfelel radj szorzataknt.
A pldban megadott adatok az albbi eredmnyt szolgltatnk:
Eredmnyek
'Viktor''
'Szilvia'
320.00
30.00
1. megolds
gy gondolom, a legjobb mdszer, hogy ltrehozunk egy nzettblt, majd ez
alapjn elvgezzk az sszegzst. Ebbl az albbi V I E W addik:
CREATE VIEW radjak (alk_id, nev, munka_datum, raszm, dijazas)
AS SELECT Hl.alk_id, nev, munka_datum, raszm,
(SELECT dijazas
FROM Dijazasok AS B0
WHERE ervenyessegi_datum = (SELECT
MAX(ervenyessegi_datum)
FROM Dijazasok AS Bl
WHERE Bl.ervenyessegi_datum
< = Hl.munka_da t ura
AND B0.alk_id = Bl.alk_id
AND B0.alk_id = Hl.alk_id))
FROM Ledolg_Orak AS Hl, Szakrtk AS El
WHERE El.alk_id = Hl.alk_id;
4. fejezet Szmtsok
2. megolds
Linh Nguyen ms megoldssal rukkolt el:
SELECT nev, SUM(oraszm*dijazas)
FROM Szakrtk AS CO, Djazsok AS BO, Ledolg_Orak AS HO
WHERE C0.alk_id = B0.alk_id
AND C0.alk_id = H0.alk_id
AND ervenyessegi_datum = (SELECT MAX(ervenyessegi_datum)
101
SQL-fejtrk
FROM Djazsok AS Bl
WHERE Bl.alk_id = C0.alk_id
AND Bl.ervenyessegi_datum <=
k HO.munka_datum)
AND HO.munka_datum >= ervenyessegi_datum
GROUP BY nev;
menny
100
120
-150
50
-35
keszlet_menny
100
220
70
120
85
4. fejezet Szmtsok
1. megolds
Az SQL-92-ben hasznlhatunk bels lekrdezst a S E L E C T listjban, a felttel csak
az, hogy eredmnyl egyetlen rtket kell szolgltatnia (innen a skalris bels le
krdezs" elnevezs), s ha a lekrdezs eredmnye res tbla, akkor az eredmny
a N U L L rtk. Az SQL-92 szabvnynak ez az rdekes szablya lehetv teszi, hogy
egy O U T E R JIN kapcsolatot a S E L E C T utastson belli lekrdezssel valstsunk
meg. Pldul az albbi lekrdezs csak akkor mkdik, ha minden gyflnek nulla
vagy egy rendelse van:
SELECT ugyf_szam, ugyf_nev,
(SELECT rend_osszeg
FROM Rendelesek
WHERE Ugyfelek.ugyf_szam = Rendelesek.ugyf_szam)
FROM gyfelek;
Ez ugyanazt az eredmnyt adja, mint a kvetkez lekrdezs:
SELECT ugyf_szam, ugyf_nev, rend_osszeg
FROM gyfelek LEFT OUTER JIN Rendelesek
ON Ugyfelek.ugyf_szam = Rendelesek.ugyf_szam;
Feladatunkban ssze kell adnunk az sszes ignylst, amit a krdses nap eltt s
azon a napon feladtak. A lekrdezs egy begyazott n-sszekapcsols, mint a k
vetkez kdrszlet is mutatja:
SELECT igny_datum, menny,
(SELECT SUM(menny)
FROM Ignylsek AS R2
WHERE R2.igny_datum <= Rl.igny_datum) AS keszlet_menny
FROM Ignylsek AS Rl
ORDER BY igeny_datum;
Azt be kell vallani, hogy ez sokkal lassabb, mint egy eljrskzpont megolds,
ami az aktulis mennyisget az elz mennyisg alapjn egy kznl lv rendezett
fjlbl is veheti.
SQL-fejtrk
2. megolds
Jim Armes a Trident Data Systemstl az elsnl nmileg egyszerbb megoldssal
llt el:
SELECT
FROM
WHERE
GROUP
O R D E R B Y Rl.igny_datum;
beoszts
'H'
'V
105
4. fejezet Szmtsok
szemly
'Kovcs'
'Tmr'
'Barna'
beoszts
'H'
'V
'X'
Az eredmnyhalmaz pedig:
Eredmnyek
szemly
'Szab'
'Kovcs'
'Tmr'
sszevont beoszts
'M'
'H'
'V
Nigel els ksrlete egy tmeneti tbla hasznlatt clozta, de ez tl lass lett volna.
Leonard C. Medal a krdsre egy lekrdezst kldtt, ami nzettblaknt is hasz
nlhat lenne s megkmli a felhasznlt az tmeneti tbla ltrehozsainak bonyo
dalmaitl. Az prblkozsa valami ilyesmi volt:
SELECT DISTINCT Rl.szemly,
CASE WHEN EXISTS (SELECT *
FROM Beosztsok A5 R2
WHERE R2.szemly = Rl.szemly
AND R2.beoszts IN ('V','0')) = V , ' 0 '
THEN 'M'
ELSE (SELECT R3.beoszts
FROM Beosztsok AS R3
WHERE R3.szemly = Rl.szemly
AND R3.beoszts IN ('V'/O'))
END AS osszevont_beosztas
FROM Beosztsok AS Rl
WHERE Rl. beoszts IN ('V, ' 0 ' ) ;
,
SQL-fejtrk
1. megolds
Prbltam a gondolatmenetet az n-sszekapcsolsok fel terelni, pedig jobban
tennnk, ha inkbb a UNlON-t hasznl megoldst rszestennk elnyben. A ketts
beosztssal rendelkez alkalmazottak ktszer fognak megjelenni, ezrt elg, ha
egyszeren megkeressk a ktszer elfordul sorokat.
SELECT
FROM
WHERE
GROUP
HAVING
UNION
SELECT
FROM
WHERE
GROUP
HAVING
Rl.szemly, MAX(Rl.beoszts)
Beosztsok AS Rl
Rl.beoszts IN ( ' V , ' 0 ' )
BY Rl.szemly
C0UNT(*) = 1
R2.szemly, 'M'
Beosztsok AS R2
R2.beoszts IN ('V','0')
BY R2.szemly
COUNT(*) = 2 ;
2. megolds
Az SQL-92 rendelkezik egy CASE kifejezssel is, amit gyakran hasznlhatunk rtk
cserre. Ezzel el is rkeztnk az utols, legegyszerbb formhoz:
SELECT szemly,
CASE WHEN COUNT(*) = 1
THEN beoszts
ELSE 'M' END
FROM Beosztsok
GROUP BY szemly;
A THEN beoszts zradk a vrakozsnak megfelelen mkdik, hiszen tudjuk,
hogy egy szemlyen bell" egyedi rtkkel kell rendelkeznie, mivel csak egyetlen
ilyen sor ltezik. Mgis, nhny SQL-termk esetleg csak a THEN MAX (beoszts)
kifejezst fogadja el ehelyett, mivel a beoszts nem szerepel a G R O U P BY zradk
ban, s gy formai hibt vl felfedezni a S E L E C T s a G R O U P B Y zradk kztt.
4. fejezet Szmtsok
1. megolds
Az egyik lehetsges mdszer, hogy egy jabb mezt hozunk ltre a mozg tlag
trolsra:
CREATE TABLE Mintk
(minta_idopont TIMESTAMP NOT NULL PRIMARY KEY;
mozgo_atlag REAL NOT NULL DEFAULT 0
ertek REAL DEFAULT 0 NOT NULL);
Ezutn egy utastssorozattal frisstjk a tblt:
UPDATE Mintk
SET mozgo_atlag
= (SELECT AVG(S1.ertek)
FROM Mintk AS Sl
WHERE Sl.minta_idopont
IN (Mintk.minta_idopont,
(Mintk.minta_idopont
- INTERVAL 15 MINUTES),
(Mintk.minta_idopont
- INTERVAL 3 0 MINUTES),
(Mintk.minta_idopont
- INTERVAL 45 MINUTES));
107
108
SQL-fejtrk
2. megolds
Nem ez az egyetlen mdja az U P D A T E utasts megrsnak. Elfordulhat, hogy
a felttelezsnk, miszerint pontosan minden 15. percben vesszk az rtkmintt,
nem mkdik; lehetnek mintavteli hibk, amelyek kvetkeztben esetleg perce
kig kihagy az idrgzt. Megprblhatjuk inkbb az egyrs idkz hasznlatt
a pontos egyezs felttelezse helyett:
U P D A T E Mintk
S E T mozgo_atlag
=
(SELECT AVG(S1.ertek)
F R O M Mintk AS Sl
W H E R E Sl.minta_idopont
BETWEEN
(Mintk.minta_idopont
- INTERVAL
1 HOUR)
A N D Mintk.minta_idopont);
3. megolds
Az utbbi U P D A T E azt sugallja, hogy ezt a felttelt egy mozg tlagot elllt lekr
dezs ltrehozsra is hasznlhatnnk:
S E L E C T Sl.minta_idopont, AVG(S2.ertek) A S elozo_ora_atlag_ertek
F R O M Mintk A S Sl, Mintk A S S2
WHERE
S2.minta_idopont
BETWEEN
(Sl.minta_idopont - I N T E R V A L
1 HOUR)
A N D Sl.minta_idopont
G R O U P B Y Sl.minta_idopont;
" 7
Adatok csoportostsa
Az SQL nem jelentskszt nyelv, mgis gyakran hasznljk egyszerbb jelentsek
elksztshez, amikor valamilyen szempont szerint csoportostva kell az adatokat
megjelenteni. Ennek oka, hogy egy gyfl-kiszolgl rendszerben a kiszolgl
rendszerint sokkalta nagyobb teljestmny gp, mint az gyfl. A munknak minl
nagyobb rszt vgzi el a kiszolgl, annl jobb lesz az sszteljestmny.
Az SQL nyelv G R O U P B Y zradka nem egyszeren a S E L E C T utasts egy klnle
ges fajtja. A G R O U P B Y olyan nem res rszekre osztja az eredeti halmazt, amelyek
nem fedik t egymst. Ezutn minden rszhalmazt egyetlen sorr alakt, amely vala
melyik csoportostsi rtkbl, skalris kifejezsbl, llandbl, sszegz fgg
vnybl vagy ezekbl alkotott valamilyen kifejezsbl szrmazik. Rviden, a cso
portostott tbla egy sora magrl a csoportrl s nem pedig a tbla valamelyik
nll rekordjrl szolgltat informcit.
A legtbb programoz a problma megoldst a S E L E C T lista felvzolsval kezdi,
ezutn a F R O M zradkba berja az sszes tblt, amiben a kvnt rtkek meg
tallhatk, vgl gondolkozni kezd azon, milyen W H E R E felttellel tudn mk
dkpess tenni a lekrdezst. Egy kis tlzssal azt is mondhatjuk, hogy az SQL
nyelvn fogalmazzk meg a Mit akarok? Hol tallom meg? Hogyan jutok hozz?"
krdshrmast.
SQL-fejtrk
110
lers
'10-es
'20-as
'30-as
'40-es
'50-es
ttel'
ttel
ttel
ttel'
ttel'
1
Eddigiek
tetelazon
10
20
20
30
eddigiosszeg
300,00
325,00
100,00
525,00
Becslesek
tetelazon
10
10
20
20
40
becsutt_osszeg
300,00
50,00
325,00
110,00
25,00
biz_szam
'iiir
'2222'
'3333'
'1111'
111
teiras
'10-es
'20-as
'30-as
'40-es
ttel
ttel'
ttel'
ttel'
eddigossz
300,00
425,00
525,00
NULL
becs ossz
35u,uo
435,00
NULL
25,00
bizszam
'1111'
'Tbb'
'1111'
NULL
A Ttelek tbla 50-es szm ttele nem szerepel, mert sem az Eddigiek, sem pe
dig a Becslesek tblban nem volt hozz tartoz rekord. Az eddigi_ossz oszlop
a ttelhez tartoz jelenlegi sszeget, a becs_ossz pedig a becslt sszeget mutatja.
Megolds
Azt hiszem, az adatbzisszerkezet is ignyelne nmi mdostst, de skalris bels
lekrdezsekkel s egy kis csel alkalmazsval megoldhat a krds.
SELECT Il.tetel_azon, Il.leiras,
(SELECT SUM (Al.eddigi_osszeg)
FROM Eddigiek AS Al
WHERE II.tetel_azon = Al.tetel_azon) AS eddigi_ossz,
(SELECT SUM (El.becsult_osszeg)
FROM Becslesek AS El
WHERE II.tetel_azon = El.tetel_azon) AS becs_ossz,
(SELECT CASE WHEN COUNT(*) = 1
THEN MAX(biz_szam)
ELSE 'Tbb' END
FROM Eddigiek AS A2
WHERE II.tetel_azon = A2.tetel_azon
GROUP BY tetel_azon) AS biz_szam
FROM Ttelek AS II
WHERE eddigi_ossz IS NOT NULL
OR becs_OSSZ IS NOT NULL;
A trkk a skalris lekrdezsekben bjik meg. Az els kett kiszmolja a jelenlegi
teljes sszeget s a becslt vgsszeget, mintha egy GROUP BY s egy LEFT OUTER
JIN rszei lennnek.
112
SQL-fejtrk
1. megolds
A kzenfekv megolds, hogy 0-t runk minden mintaazonost al, ahol nem sze
repel az adott hal, vagyis nem engedjk meg a hinyzst. Ez a mdszer lehetv te
szi az eredeti lekrdezs hasznlatt. A hinyz sorok beszrshoz a kvetkez
utastst hasznlhatjuk:
INSERT I N T O Mintk
SELECT Ml.minta_id, M2.hal, 0
FROM Mintk AS Ml, Mintk AS M2
114
SQL-fejtrk
2. megolds
Sajnos kiderl, hogy tbb mint 100 000 klnbz halfajta ltezik s a mintk sz
ma is tzezres nagysgrend. Az alkalmazott trkk tbb helyet foglalna, mint
amennyivel a halr rendelkezik. Az SQL-92 fogsait kell alkalmaznunk ahhoz, hogy
egyetlen utastssal megoldhassuk a feladatot:
SELECT hal, SUM(talalt_db)/
(SELECT COUNT(minta_id)
FROM MintaCsoportok
WHERE csoport_id = :vizsg_csoport)
FROM Mintk
WHERE hal = :vizsg_hal
GROUP BY hal;
A skalris bels lekrdezs kifejezse az tlagszmts szablyt alkalmazza, misze
rint az rtkek sszegt osztani kell az sszegben szerepl tagok szmval. Az SQL
azonban egy kicsit trkksebb.
A SUM () kifejezs az osztandban akkor ad vissza N U L L rtket, ha res halmaz az
eredmny. Ez esetben a trt (hnyados) rtke is N U L L . A skalris bels lekrdezs
az osztandban abban az esetben lehet N U L L , ha az eredmny res halmaz, hiszen
a lekrdezsben szerepl sszest fggvny eredmnye abban az esetben lehet
nulla, ha a paramterknt megadott halmaz res.
A C O U N T (<kifejezs>) sszest fggvny eredmnye egy tblnl csak akkor le
het N U L L , ha abban csak N U L L rtkek szerepelnek. Mivel mi a tblk megadsnl
ezt kizrtuk, ez biztosan nem kvetkezhet be.
3. megolds
A Kansas llambeli Anilbabu Jaiswal egy kiss eltr Oracle-megoldst kldtt,
amelynek SQL-92 vltozata gy fest:
116
SQL-fejtrk
AlkalmassagiJelentes
hallgat
Robi
Jzsi
Jnos
Mari
megfelelt
nem_felelt_meg
X
X
X
X
imo
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
( Jzsi , 'A' 3) ;
('Jzsi , 'A' 2) ;
('Jzsi ', 'A' 3) ;
('Jzsi ', 'A' , 3) ;
('Jzsi , 'B' 3) ;
('Jzsi '. C ' 3) ;
('Jzsi ', ' C ' 2) ;
('Jzsi' , ' C ,' 3) ;
('Robi', ' A' ,2) ;
('Robi , 'C , 2) ;
('Robi', 'A' , 12) ;
('Robi', c , 4) ;
('Jnos' , 'A' 1) ;
('Jnos' , 'B' , 100
('Mari', 'A' , 1) ;
('Mari', ' A ' ,1) ;
('Mari', 'A , 1) ;
('Mari', ' A ' ,
1) ;
('Mari', 'A' , 1) ;
('Mari', ' A' ,1) ;
('Mari', 'A' , 1) :
1
117
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
SzerzettKreditek
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
( Mari',
('Mari ,
('Mari',
('Mari',
('Mari',
('Mari',
('Mari',
('Mari',
('Mari',
('Mari',
('Mari',
('Mari',
('Mari',
('Mari',
('Mari',
('Mari,
('Mari',
('Mari',
('Mari',
1
'A'
'A'
'A'
'A'
, 1)
, 1)
, 1)
. 1)
' s , 1)
' S ' 1)
,
' S ' 1)
,
' S ' 1)
,
'B' , 1)
'B' , 1)
' S ' 1)
,
1)
c,
'C , 1)
'C , 1)
'C , 1)
'C , 1)
C ' ,1)
'C ' ,1)
'C , 1)
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
,
,
SQL-fejtrk
Eredmnyek
hallgat
Robi
Jzsi
Jnos
Mari
megfelelt
nemfeteftmeg
X
X
X
X
Prok
modeti_a
modellj)
123 i5
12345
67890
12315
67890
12345
darabszm
12
9
5
modellj)
darabszm
12345
12345
12345
67890
12
14
modellj)
123
12345
67890
123-15
67890
12345
darabszm
24
14
14
Abbott egy olyan kd rst fontolgatta, ami megkeresi a fordtott prokat, hozzad
ja az rtket s trli a rekordot, mikzben az azonos modellszm modellprokat
tugorja, de mg remnykedett abban, hogy ltezik SQL-megoldsa a feladatnak.
SQL-fejtrk
1. megolds
A korbbi lekrdezs knnyen kijavthat:
SELECT S0.modell_a, SO.modelljo, SUM(SO.darabszm + Sl.darabszm)
AS darabszm,
FROM Nyugtk AS SO, Nyugtk AS Sl
WHERE S0.modell_a <= S0.modell_b
AND S0.modell_a = Sl.modelljo
AND S0.modell_b = Sl.modell_a
GROUP BY S0.modell_a, S0.modell_b, Sl.modell_a, Sl.modelljo;
Az n-sszekapcsols meglehetsen erforrs-ignyes, s igazbl nincs is r szk
sg. Nhny SQL-alkalmazsban (az ACCESS nem tartozik ezek kz) esetleg a k
vetkez formt is hasznlhatjuk:
SELECT CASE WHEN modell_a <= modell_b
THEN modell_a
ELSE modelljo END AS ml,
CASE WHEN modell_a <= modell_b
THEN modell_b
ELSE modell_a END AS m2,
SUM (darabszm)
FROM Nyugtk
GROUP BY ml, m2;
2. megolds
Ha az SQL-89 szablyai szerint szeretnnk ugyanezt megvalstani, elszr egy n
zettblba kellene tennnk a tblzatos bels lekrdezs eredmnyt, majd ezt
a viEW-t hasznlhatnnk egy msik lekrdezsben. Igazbl ugyanarrl a kdrl
van sz, csak kln lpsekre bontottuk a megoldst, aminek megvan az az el
nye, hogy a nzettbla ms jelentsekben is felhasznlhat.
CREATE VIEW Jelents (ml, m2, darabszm)
AS SELECT CASE WHEN modell_a <= modell_b
THEN modell_a
ELSE modell_b END,
CASE WHEN modell_a <= modelljo
THEN modell_b
ELSE modell_a END,
darabszm
FROM Nyugtk;
SELECT ml, m2, SUM(darabszm)
FROM Jelents
GROUP BY ml, m2;
3. megolds
A legjobb mdszer mgis az, ha az adatbzist vltoztatjuk meg a lekrdezs eltt
oly mdon, hogy a modell_a a kt kdszm kzl mindig a kisebb rtkt tartal
mazza. Ez igen egyszeren megvalsthat:
UPDATE Nyugtk
SET modell_a = modell_b,
modell_b = modell_a
WHERE modell_a > modell_b;
Ugyanezt egy kiold (trigger) hasznlatval s beszrssal is megvalsthattuk volna.
42.feladvny - Pepperoni
Egy klasszikus szmolsi feladat jelentst rni a korbbi szmlzsok idbeli rendj
rl. Szerepeljen a pldnkban a Pepperoni bartai nev klub, amelynek hitelkrty
jt elfogadjuk a pizzerinkban. J lenne, ha mindig tudnnk, hogy a klubtagok ren
delkeznek-e mg megfelel kerettel a hitelkrtys vsrlshoz.
122
SQL-fejtrk
1. megolds
Lekrdezst rhatunk egyenknt a megfelel idtartamokra, majd a UNION mvelet
tel egyesthetjk ezeket:
1
2. megolds
Ne hasznljunk U N I N mveleteket, ha helyette rendelkezsnkre l a CASE.
A UNiON-ok hasznlatval tbbszr vgig kell vizsglnunk a tblt, mg a CASE kife
jezssel csak egyszer.
SELECT ugyf_azon,
SUM(CASE WHEN szamla_datum
BETWEEN CURRENT_TIMESTAMP
AND CURRENT_TIMESTAMP
THEN sszeg ELSE 0.00) AS
SUM(CASE WHEN szamla_datum
BETWEEN CURRENT_TIMESTAMP
AND CURRENT_TIMESTAMP
THEN sszeg ELSE 0.00) AS
SUM(CASE WHEN szamla_datum
BETWEEN CURRENT_TIMESTAMP
AND CURRENT_TIMESTAMP
THEN sszeg ELSE 0.00) AS
SUM(CASE WHEN szamla_datum
< CURRENT TIMESTAMP THEN sszeg ELSE 0.00) AS
FROM PepperoniBaratai;
- INTERVAL 3 0 DAYS
idotartaml,
- INTERVAL 60 DAYS
- INTERVAL 31 DAYS
idotartam2,
- INTERVAL 9 0 DAYS
- INTERVAL 61 DAYS
idotartam3,
INTERVAL 91 DAYS
idotartam4
123
SQL-fejtrk
kezdodatum
'1995-02-01'
'1995-11-Or
'1995-12-18'
ert_datum
sszeg
'1995-U2-IJ3'
250,99
250,99
100,00
400,98
400,98
4,98
257,50
110,00
300,98
'1995-02-03'
'1995-02-04'
'1995-02-05'
'1995-12-19'
'1995-12-20'
'1995-02-03'
'1995-02-04'
'1995-02-05'
1995-ii-or
'1995-11-01'
'1995-11-02'
'1995-12-23*
'1995-12-24'
'1995-11-01'
'1995-11-01'
'1995-11-03'
'1995-12-18'
'1995-12-19'
'1995-12-20'
'1995-01-04'
150,25
325,00
150,75
257,50
25,50
325,00
999,75
150,00
800,00
100,00
200,00
100,00
bef datum
'1995-U2-07'
'1995-11-07'
'1995-12-25'
1. megolds
Az albbi lekrdezs lnyege, hogy kiszmtjuk az egyes eladk ltal az adott akci
ban eladott rtk sszegt, majd ezen csoportokbl kivlasztjuk a legnagyobb
sszeget. Az els rsz egy viszonylag egyszer JOIN s GROUP BY zradkokat al
kalmaz utasts.
A legnagyobb sszeg megkeresse az egyes csoportokban mr ignyel egy trkks
HAVING zradkot. Nzzk elszr a megoldst, utna a magyarzatot:
SELECT El.elad, Al.akci, SUM(El.sszeg) AS ossz_eladas
FROM Ertekesitesek AS El Akcik AS Al
WHERE El.ert_datum BETWEEN Al.kezdo_datum AND Al.bef_datum
GROUP BY El.elad, Al.akci
HAVING SUM(sszeg) >=
ALL (SELECT SUM(sszeg)
FROM Ertekesitesek AS E2
WHERE E2.elado <> El.elado
AND E2.ert_datum
BETWEEN (SELECT kezdo_datum
FROM Akcik AS A2
WHERE A2.akcio = Al.akcio)
AND (SELECT bef_datum
FROM Akcik AS P3
WHERE P3.akcio = Al.akcio)
GROUP BY E2.elado);
Azt szeretnnk, ha a kivlasztott elad akcin belli eladsainak sszege egyenl
vagy nagyobb lenne az sszes tbbi elad adott akcihoz tartoz rtkestsi
sszegnl. Az E2 . elado <> El. elado felttel kizrja a tbbi eladt az sszegkp
zs lekrdezsbl. A BETWEEN felttelben lv kifejezs bels lekrdezsei bizto
stjk, hogy j dtumokat hasznlunk az akcihoz.
A lekrdezs javtsn elmlkedve az els gondolat az lehet, hogy a BETWEEN felt
tel bels lekrdezseit kzvetlen kls hivatkozsra cserljk:
SELECT El.elado, Al.akcio, SUM(El.sszeg) AS ossz_eladas
FROM Ertekesitesek AS El Akcik AS Al
WHERE El.ert_datum BETWEEN Al.kezdo_datum AND Al.bef_datum
GROUP BY El.elado, Al.akcio
HAVING SUM(sszeg) >=
ALL (SELECT SUM(sszeg)
125
126
SQL-fejtrk
FROM rtkestsek AS E2
WHERE E2.elad <> El.elad
AND E2.ert_datum -- Hiba !!
BETWEEN Al.kezdo_datum AND Al.bef_datum
GROUP BY E2.elad);
2. megolds
A GROUP BY El. elad, Al. akci zradk olyan csoportostott tblt hozott ltre,
ami csak sszegz fggvnyeket s kt csoportostott oszlopot tartalmaz. A F R O M
zradkban ltrejv eredeti munkatblt megszntettk, a csoportostott munka
tbla vltotta fel, gy a kezdo_datum s a bef_datum szintn megsznik ltezni
ezen a ponton.
Jllehet a bels lekrdezs kifejezse mkdik, mert az Al kls tblra hivatko
zik, ami mg mindig elrhet, hiszen a lekrdezs a legbels lekrdezsbl dolgo
zik, nem pedig a csoportostott tblbl. Ha a teljestmnyre kt ismert, lland d
tum kztt lennnk kvncsiak, a msodik lekrdezs is mkdne, ha az
Al. kezdo_datum s az Al. bef_datum rtkeket kicserlnnk ezekre az lland
dtumrtkekre.
Rovatom kt olvasja kldtt erre a problmra javtott megoldsokat: Richrd
Romley s J. D. McDonald. Mindketten megemltik, hogy ha felttelezzk, hogy az
akcik nem fedik t egymst, akkor az Akcik tbla csak kulcsmezkkel rendelke
zik, gy az (akci, statdate, bef_datum) kifejezs hasznlata a GROUP BY zra
dkban nem vltoztatja meg a csoportostst. Ezzel a kezdo_datum s a bef_datum elrhetv vlik a HAVING zradk szmra, vagyis:
SELECT El.elad, Al.akci, SUM(El.sszeg) AS ossz_eladas
FROM rtkestsek AS El Akcik AS Al
WHERE El.ert_datum BETWEEN Al.kezdo_datum AND Al.bef_datum
GROUP BY Al.akci, Al.kezdo_datum, Al.bef_datum. El.elad
HAVING SUM(El.sszeg) >
ALL (SELECT SUM(E2.sszeg)
FROM rtkestsek AS E2
'Nemzeti klykpard'
'Szilvi'
0.00
'Lajos'
626.00
'Laura'
1474.75 <== Nyertes
'Karcsony
'.viivi'
'Lajos'
'Laura'
hete'
io5.yo
283.00
1100.00 <== Nyertes
127
128
SQL-fejtrk
kezd
1
6
10
16
befejez
4
7
15
18
A feladat egy olyan megszorts ltrehozsa a tblhoz, ami biztostja, hogy a fel
vett foglalsok soha ne lehessenek fedsben. A krds bonyolultabb, mint els r
nzsre gondolnnk, hacsak nem lpsenknt oldjuk meg a problmt.
1. megolds
Az els vltozat egy C H E C K () zradk alkalmazsa lehetne. Esetleg felrajzolhatunk
nhny vzlatot azzal kapcsolatosan, hogy az lsszakaszok hnyflekppen fed
hetik egymst, s valami ilyesmit kaphatunk eredmnyknt:
C R E A T E TABLE Foglalasok
(tulajdonos CHAR(IO) NOT NULL PRIMARY KEY,
kezd INTEGER NOT NULL,
befejez INTEGER NOT NULL,
CONSTRAINT Nincs_atfeds
CHECK (NOT EXISTS
( S E L E C T Rl.tulajdonos
FROM Foglalasok AS Rl
W H E R E kezd BETWEEN Rl.kezd AND Rl.befejez
OR befejez BETWEEN Rl.kezd AND Rl.befejezo)));
Ez egy gyes fogs, amellyel a ktszer szerepl kezd s befejez lhelyek
ugyangy kiszrhetk, mint az tfedsek.
2. megolds
Kt gond addik. Az SQL-92 Intermediate szintje nem engedi meg a CHECK () zra
dkban lev bels lekrdezseket, de a Full SQL-92 igen, gy elfordulhat, hogy az
ltalunk hasznlt alkalmazssal ez a megolds nem fog mkdni. Ha krbejrjuk
a problmt, esetleg azt tapasztalhatjuk, hogy nem tudjuk felvenni az els helyfog
lalst. A P R I M A R Y K E Y s a N O T N U L L megszortsokkal nem lehet baj. Ezzel szem
ben amikor az rtelmez a CHECK () megszortshoz r, a bels lekrdezs alapjn
Rl nven egy msolatot kszt az res Foglalasok tblrl.
Innentl kezdve a dolog kezd egy kicsit zavaross vlni. Az Rl. kezd s
Rl .befejez rtkek a C R E A T E T A B L E utasts szerint nem lehetnek N U L L rtk
ek, viszont az Rl res, vagyis mgis N U L L rtkek lesznek a B E T W E E N felttelben.
J eslynk van r, hogy ez az nmagra mutat hivatkozs megzavarja a megszo
rts-ellenrzt, s nem fogunk tudni els sort felvinni a tblba. A legbiztonsgo
sabb eljrs, ha meghatrozzuk a tblt, felvesznk egy vagy kt sort, majd ezutn
adjuk hozz a Nincs_atfeds megszortst.
129
130
SQL-fejtrk
Fel szerette volna bontani a tblt, ami annyit jelent, hogy olyan nzettblt vagy
valdi tblt akart ltrehozni, ami kln sorral rendelkezik minden alkotelem sz
mra. Pldul az eredeti tblban szerepl ( CD-ROM' , 3) rekordhoz 3 kln sort
szeretett volna, amelyek mindegyikben a ( C D - R O M ', 1) rtkek szerepelnek. Mi
eltt felmerlne a krds, sietek kijelenteni: fogalmam sincs rla, hogy erre mirt
volt szksg - tekintsk egyszeren gyakorlfeladatnak.
1
1. megolds
llandan hangslyozom, hogy ha az SQL-ben programozunk, akkor halmazokban
kell gondolkodnunk. A legjobb megolds megtallsnak egyik mdja az ismtelt
sorbeszrsok alkalmazsa az eredeti tbln, ami a szmtstechnika hskorban
osztsi s szorzsi mveletekre hasznlt orosz paraszt algoritmus" elvre pl. Ha
kvncsiak vagyunk r, matematikatrtnettel vagy szmtstudomnnyal foglalkoz
knyvekben megtallhatjuk ezt a binris aritmetikra pl, az assembly nyelvek
ben balra, illetve jobbra lptet mveletekkel megvalsthat programozsi eljrst.
Mg mindig szksgnk lesz nmi negyedik genercis kdolsi tudsra, de ez
mr nem lesz olyan vszes. Elszr is hozzunk ltre kt munkatblt, egyet pedig
a vgeredmny szmra:
CREATE TABLE Munkatablal
(aru CHAR(IO) NOT NULL,
darabszm INTEGER NOT NULL);
SQL-fejtrk
Munkatabla2
darabszm
4
5
16
50
aru
darabszm
Munkatabla2
darabszm
aru
Alia
'Alfa'
'Bta'
'Bta'
'Delta'
'Delta'
'Gamma'
'Gamma'
1
darabszm
2
2
2
3
8
8
25
25
aru
Munkatabla2
'Alfa'
'Alfa'
'Alfa'
'Alfa'
'Bta'
'Bta'
'Bta'
'Bta'
'Bta'
darabszm
aru
darabszm
1
1
1
1
1 Az 'Alfa' s a 'Bta' kszen llnak a begyjtsre
1
1
1
1
'Delta'
'Delta'
'Delta'
'Delta'
'Gamma'
'Gamma'
'Gamma'
'Gamma'
4
4
4
4
12
12
13
13
A teljes kirts ideje ltalban igen rvid. Ugyangy a sorok msolsnak idig
nye (ezek a lemezen ltalban fizikai blokkok, amelyeket teljes tmeneti trknt
mozgathatunk) egyik tblbl a msikba sokkal kisebb, mint egyenknt beszrni
a sorokat.
A kdot gy is megrhattuk volna, hogy az eredmny az egyik munkatblban ke
letkezzen, de ez a megkzelts lehetv teszi, hogy a munkatblk egyre kisebbek
legyenek, gy jobb az tmeneti tr kihasznltsga. Az algoritmus ( S E L E C T
SUM (darabszm) FROM Raktrkszlet) szm sort trol s (log2 ( ( S E L E C T
MAX (darabszm) FROM Raktrkszlet) ) +1) mozgatst vgez, ami mindkt
szempontbl j eredmnynek mondhat.
133
SQL-fejtrk
2. megolds
Pter Lawrence a CompuServe-n egy msik megoldst javasolt erre a feladvnyra.
Elszr hozzunk ltre egy tblt, ami az sszes egsz szmot tartalmazza, legalbb
a darabszmok legnagyobb rtkig (n):
CREATE TABLE Darabszam_tabla (darabszam_ssz INTEGER NOT NULL);
INSERT INTO Darabszam_tabla VALUES ( (1) , (2) , ..., (n));
A lekrdezs pedig legyen a kvetkez:
SELECT
FROM
WHERE
AND
Eredmnyek
aru
'CD-ROM'
'CD-ROM'
'CD-ROM'
'Nyomtat'
'Nyomtat'
jgPfeszam
rabszam_ssz
1
1
1
2
1
1
1
3
1
2
(2));
Egy msik megkzelts alapjn a lekrdezs nem hajtdik vgre, ha van olyan da
rabszmunk, amely nagyobb a darabszam_ssz maximumnl:
SELECT aru, 1 AS darabszm, darabszam_ssz
FROM Raktrkszlet AS II, Darabszam_tabla AS TI
135
136
SQL-fejtrk
(9));
INTO Darabszam_tabla
((Dl.i) + (10 * DIO.i) + (100 * D100.)) AS ssz
Szmjegyek AS Dl, Szmjegyek AS D10, Szmjegyek AS Dl00
ssz <= (SELECT MAX(darabszam) FROM Raktrkszlet);
Megolds
Az els lekrdezs nem jelent gondot:
SELECT term_kozpont, term_datum, COUNT(adag_sorszam,
AVG (eszkoz_db)
FROM Termeles
GROUP BY term_kozpont, term_datum;
137
138
SQL-fejtrk
|
i
li
1. megolds
Az els gondolatunk, hogy ez egy egyszer csoportostott lekrdezs az albbi
formban:
SELECT cikkiro_azon, cikkiro_nev, :elso_kat, :masodik_kat,
:harmadik_kat
FROM Antolgia AS Al,
WHERE Al.kategria IN (:elso_kat, :masodik_kat, :harmadik_kat)
GROUP B Y cikkiro_azon, cikkiro_nev
HAVING COUNT(*) = 2;
Ez a megolds sajnos nem mkdik, mert elfordulhat, hogy a cikkr kt cikke
ugyanabba a kategriba tartozik. Szksgnk lenne mg egy ( C O U N T ( D I S T I N C T
<kifejezes>) tpus felttelre is. A lekrdezs mg gy is nagyon egyszer:
SELECT cikkiro_azon, cikkiro_nev, :elso_kat, :masodik_kat,
:harmadik_kat
FROM Antolgia AS Al,
WHERE Al.kategria IN (:elso_kat, :masodik_kat, :harmadik_kat)
GROUP B Y cikkiro_azon, cikkiro_nev
HAVING COUNT(DISTINCT Al.kategria) = 2 ;
Tudnnk tallni olyan megoldst, ami nem hasznlja a GROUP B Y zradkot? Hozz
teszem, hogy nem javaslom az itt kvetkez megoldsok hasznlatt, a gyakorlat
clja, hogy megfelel mdon rtkeljk a GROUP B Y zradk lehetsgeit.
139
SQL-fejtrk
2. megolds
A feladatmeghatrozs nem tr ki arra, hogy a hrom kategria kzl brmelyik
kett vlaszthat-e, vagy meghatrozott sorrendben kell lennik (pldul az l-es s
2-es kategriban szerepel, de a 3-asban nem). Ezzel az utbbi kiktssel knnyen
rhatunk egy lekrdezst:
SELECT Al.cikkiro_azon, Al.kategria, A2.kategria
FROM Antolgia AS Al,
Antolgia AS A2
WHERE Al.cikkiro_azon = A2.cikkiro_azon
-- n-sszekapcsols
AND Al.kategria = :elso_kategoria -- l-es kategria
AND A2.kategria = :masodik_kategoria -- 2-es kategria
AND NOT EXISTS (SELECT *
-- de nincs 3-as kategria
FROM Antolgia AS A3
WHERE Al.cikkiro_azon = A3.cikkiro_azon
AND A3.kategria = :harmadik_kategoria));
3. megolds
Ha olyan lekrdezst keresnk, amely brmely kett kategrit engedi a hrom k
zl, szksgnk van valamilyen programozsi trkkre. Az albbi megolds nem ha
trozza meg, hogy a hrom kzl melyik kett hinyzik:
SELECT cikkiro_azon, cikkiro_nev, :elso_kat, :masodik_kat,
W :harmadik_kat
FROM Antolgia AS Al,
WHERE Al.kategria IN (:elso_kat. :masodik_kat, :harmadik_kat)
AND EXISTS
(SELECT *
FROM Antolgia AS A2,
WHERE A2.kategria IN (:elso_kat. :masodik_kat,
:harmadik_kat)
AND Al.kategria < A2.kategria
AND Al.cikkiro_azon = A2.cikkiro_azon
AND NOT EXISTS
(SELECT *
FROM Antolgia AS A3,
WHERE A3.kategria
IN (:elso_kat, :masodik_kat,
:harmadik kat)
141
142
SQL-fejtrk
Elirnyzat
feladat
1
2
3
4
5
kategria
9100
9100
9100
9200
9200
becsktg
100,00
15,00
6,00
8,00
11,00
feladat
1
1
1
2
4
5
5
tenylegesar
10,00
20,00
15,00
32,00
8,00
3,00
4,00
Jelenlegiertek
bizonylatiertek
1
2
3
4
5
6
7
becslt
121,00
19,00
elklttt
77,00
15,00
Az albbi eredmnnyel:
Eredmny
kategria
9100
9200
becslt
32lj>n
30,00
elklttt
77,00
15,00
Megolds
Bob Badour egy olyan SQL-89-ben rt nzettblt javasolt, amivel szerinte megkap
hatjuk a kvnt kimenetet:
CREATE VIEW kat_ktg (kategria, becs_ktg, tenyleges_ar)
AS SELECT kategria, becs_ktg, 0.00
FROM Elirnyzat
UNION
SELECT kategria, 0.00, tenyleges_ar
FROM Elirnyzat, Jelenlegi_ertek
WHERE Elirnyzat.feladat = Jelenlegi_ertek.feladat;
A nzettblt a kvetkez lekrdezs kveti:
SELECT kategria, SUM(becs_ktg), SUM(tenyleges_ar)
FROM kat_ktg
GROUP BY kategria;
Az SQL-92 lehetv teszi, hogy az albbi mdon JIN kapcsolatot hozzunk ltre az
egyes feladatokra elklttt teljes sszegek s az Elirnyzat tblban lv kate
gria kztt:
SELECT Bl.kategria, SUM(becs_ktg), SUM(elklttt)
FROM Elirnyzat AS Bl
LEFT OUTER JIN
SQL-fejtrk
O N Al.feladat = Bl.feladat
G R O U P BY Bl.kategria;
nev
Dri
Jzsi
Erika
Nikolett
Katalin
Szarni
Szaml
ERT
ERT
ERT
Az albbi eredmnnyel:
Eredmny
osztjeon
COUNTD
Szaml
ERT
2
3
s
SELECT COUNT(*) / COUNT(DlSTINCT oszt_azon)
FROM Szemlyzet;
Megolds
Az els megolds fogja az osztlyok azonostit, eldobja a N U L L rtkeket (ebben az
esetben nem is szabad ilyennek lenni benne), ezutn elhajtja a ktszer szereplket,
majd a maradkot tlagolja. Ennek semmi kze az egyes osztlyokon dolgoz alkal
mazottak szmhoz, pldul az (1 + 2/2) = 1,5 eredmnyt kaphatjuk vlaszknt.
A msodik lekrdezs igazbl sokkal jobb, s az adatainknl helyes eredmnyre is ve
zet. Kiszmolja a C O U N T (*) = 5 rtket, majd elosztja a C O U N T (DISTINCT (oszt_azon))
= 2 eredmnnyel, ami valban 2,5-et ad vgeredmnyl, ahogy kvntuk.
SQL-fejtrk
146
nev
Dri
Jzsi
Erika
Nikolett
Katalin
Laci
Mni
Kriszta
Szaml
Szaml
ERT
ERT
ERT
NULL
NULL
NULL
COUNTC)
2
3
3
A plya mez a plya nevt tartalmazza, ahol a versenyt rendezik, a verseny_datum a verseny dtumt, a futam a futam szmt, a maradk hrom oszlop pedig
a nyer, a msodik s harmadik helyezett l nevt trolja.
Egy nap a Doktor azzal fordul hozznk, hogy tudni akarja, az egyes lovak hnyszor
hoztak pnzt a konyhra. Milyen SQL lekrdezst rnnk erre?
1. megolds
A pnzt hoz a konyhra" kifejezs mgtt az ll, hogy a l a hrom helyezs kzl
elrte valamelyiket, most lnyegtelen, hogy melyiket. Az els lps egy VIEW ltre
hozsa az sszegzett adatokkal, vagyis:
CREATE VIEW Fizetsek (lo, alkalom, helyezs) AS
SELECT els, COUNTf*), 'els'
FROM Versenyeredmnyek
GROUP BY els
UNION
SELECT msodik, COUNT(*), 'msodik'
FROM Versenyeredmnyek
GROUP BY msodik
UNION
SELECT harmadik, COUNT(*), 'harmadik'
FROM Versenyeredmnyek
GROUP BY harmadik;
148
SQL-fejtrk
2. megolds
Ha van egy olyan tblnk, amiben szerepel az sszes l, az albbi mdon is megr
hatjuk a lekrdezst:
SELECT
FROM
WHERE
GROUP
Ll.lo, COUNT(*)
LoNevek AS Ll, Versenyeredmnyek AS El
Ll.lo IN (El.elso, El.msodik, El.harmadik)
BY Ll.lo;
lennik xO 1-tl kezdden, ahol x az adott szint szma. A szlloda elg kicsi ah
hoz, hogy biztosak lehessnk abban, hogy elegend a hromjegy szmok haszn
lata. A tbla meghatrozsa gy fest:
CREATE TABLE Szlloda
(emelet SMALLINT NOT NULL,
szoba SMALLINT NOT NULL,
PRIMARY KEY (emelet, szoba),
FOREIGN KEY emelet REFERENCES Epulet(emelet);
Pillanatnyilag az albbi adatokat troljuk a tblban:
emelet
1
1
1
2
2
3
NULL
NULL
NULL
NULL
NULL
NULL
1. megolds
A WATCOM-ot hasznl programozk a kvetkez megkzeltst vlasztottk. El
szr futtassunk le egy olyan frisstst az egsz adatbzison, ami feltlti a szobasz
mokat. Ez a fogs csak gy mkdhet, ha biztostani tudjuk, hogy a Szlloda tb
la frisstse rendezett sorrendben trtnjen. Trtnetesen a WATCOM egy egyszer
O R D E R B Y zradkkal kpes ezt garantlni az U P D A T E utastsban:
149
150
SQL-fejtrk
UPDATE Szlloda
SET szoba = (emelet*100)+NUMBER(*)
ORDER BY emelet;
Ezzel a kvetkez eredmnyt kapjuk:
emelet
1
1
1
2
2
3
101
102
103
204
205
306
emelet
1
1
1
2
2
3
101
102
103
201
202
301
2. megolds
Az SQL utastsok ltrehozsra magt az SQL-t fogom hasznlni. Ez gyes csel,
amit a gyakorlatban nem igazn hasznlnak ki. Fontos, hogy jl figyeljnk az
aposztrfokra s ne felejtsk a szmokat karakterlncc alaktani.
SELECT DISTINCT
'UPDATE Szlloda SET szoba = ('
II CAST (emelet AS CHAR(l))
II ' * 100)+NUMBER(*) WHERE emelet = '
II CAST (emelet AS CHAR(1)) II
FROM HamisTabla;
Az utasts eredmnye egyetlen szveges oszlop lesz:
UPDATE Szlloda SET szoba = (emelet*100)+NUMBER(*) WHERE emelet = 1;
UPDATE Szlloda SET szoba = (emelet*100)+NUMBER(*) WHERE emelet = 2;
UPDATE Szlloda SET szoba = (emelet*100)+NUMBER(*) WHERE emelet = 3;
151
Trgymutat
A
#
ltalnos szlsrtk 44
ACCESS 120
altats 11
adatpsg-ellenrzs 50
AND mvelet 55
adatfolyam-diagramok 75
adatformzs 34
adatkivlaszts 49
aposztrf 51
adatmeghatrozs 1
tlagfggvny 86
adatok formzsa 17
tlagos kltsg 97
adatszerkezeti problmk 1
tlagszmts 114
adszmts 92
adzsi krzet 92
AFD75
tmeneti tr 133
Alan Flancman 69
alapbr 43
azonost 51
alkatrszek 78
ALL felttel 80
lland 8
lland tbla 135
alperes 34
ltalnos skalris alkifejezsek 43
BASIC 33
begyazott n-sszekapcsols 103
begyazott OUTERJOIN kapcsolatok
42
SQL-fejtrk
brleti dj 65
CREATE VIEW 2
Beit Scalzo 7
csillag 8
beszlltk 78
BETWEEN llts 19
Bipin C. Desai 78
CREATE ASSERTION 2
CREATE TABLE utasts 3
CURRENT_DATE fggvny 90
brsgi kereset 34
biztonsgi azonostk 15
Bob Badour 143
Brendan Campbell 38
DB2 9, 46
Brian K. Buckley 99
Delphi 55
Brian Young 72
DeMorgan-trvny 68
C, Cs
denormalizlt adatbzis 1
Dewey-kd 2
Carl C. Federl 68
diagram-ellenrz eljrs 76
CASE frum 75
diplomaszerzs 115
CASTO 33
DISTINCT zradk 78
CEILING 131
Cenk Ersoy 31
dntsi tbla 68
CHECKO megszorts 1
DOT 55
Dr. Nyrfs 10
Diosdado Nebres 96
E,
egyenl halmazok 78
egymsba gyazott halmazok 20
egy-sok kapcsolat 141
157
Trgymutat
egyszeres idzjel 51
FORMAT 33
eleme 78
FORMAT utasts 17
Elmasri 78
elforduls 78
formtumra vonatkoz
megszortsok 17
Fortran 33
els(n) fggvny 44
frissts 149
FROM kifejezs 58
eltelt napok 88
epszilon 78
fggvnyknyvtrak 83
erforrs-igny 120
rtkcskkens 96
rtkestk 60
futsid 78
rzstelents 10
eszkzgyr 136
tterem 27
EXISTSO 141
EXISTSO llts 8
EXISTSO fggvny 68
G,Gy
Gantt-diagram 11
Gerard Manko 49
Gerhard F. Jilovec 96
Gillian Robertson 92
GROUP BY 58
GROUP BY zradk 7, 37, 96, 104,
109, 125, 139, 149
Fabian Pascal 43
feladatazonost 50
Gupta 42
felesleges szkzk 17
feltteles lltsok 71
frhelyek 26
fizikai brzols 17
fiat table 74
FLOOR 131
folyamatbrk 75
folyamatok 49
folyamattpusok 51
folyiratok 66
FOREIGN KEY 50
H
halmazelmlet 78
halmazok 130
halr 112
halszmlls 112
harmadik genercis nyelvek 43
hrombl kett 139
hatkr 16
158
SQL-fejtrk
helyirtk 136
hivatkozsi psg 50
kapcsolt allekrdezs 58
hivatkozsi megszortsok 66
IBM 60, 78
karakterlnc-sszefzs 33
Karn Gallaghar 65
idkezel fggvnyek 5
Keith McGregor 66
ignyls 102
keressi felttel 55
illetk 104
ketts idzjel 51
INO felttel 78
INO prediktum 71
kezdet-esemny 13
INNERJOIN 79
kiold 121
INSERT INTO 33
kirts 133
kdfordt tbla 37
INSERT utasts 75
kdolsi rendszer 2
interpolci 85
kdolsi sma 2
iratok 19
kltsgek 141
kltsgvetsi v 3
J. D. McDonald 126
koszinusz 83
Jack Wells 43
kzelts 85
korrellt allekrdezs 58
jelents 104
kzpkori r templomok 2
jelzmez 26
kulcs 122
kulcsmezk 126
Jim Chupella 5
JIN 81, 125
Trgymutat
kulcssz 51
mrfldkvek 72
kls sszekapcsols 41
metszet 81
kurzorelhelyez utasts 43
Mike Conway 47
kszbrtk 68
MINO 39
mintavteli hibk 108
L
LanSoft Inc. 110
Larry Wade 54
LEFT OUTER JIN 48, 51, 66, 111,
115, 118, 144
modellprok 118
mdusz 86
mozg tlag 107
Mr. Shankar 63
MS-ACCESS frum 5, 28, 54, 118
munkaegysgek 97
munkahelyi tvollt 5
munkakzvett 54
lekrdezs-kszt 90
leltrozs 102
Leonard C. Medl 10, 34, 105
lineris kzelts 85
munkarend 31
munkaviszony 28
mutatlncok 20
mtt 10
M
Mark Frontra 110
N Ny
f
Navthe 78
negatv rtkek 70
nem sszefgg llandlista 96
nested sets 20
nzettbla 2, 76, 144
Nigel Blumenthal 104
normalizls 49
msols 133
MAXO 39
megjelentsi problmk 36
NULL rtk 3
megszorts-ellenrz 129
NUMBERC) 149
SQL-fejtrk
nyomtatk idbeosztsa 24
PowerSoft 99
nyugdjalap 28
Primary 51
PRIMARY KEY 26, 51, 53, 129
0,
oktatk 38
radin 84
Raymond Petersen 88
OR mvelet 56
REFERENCES zradk 53
reklmlevl 58
Oracle Corporation 7
rendezs 104
replgpek 64
rszhalmazok 78
rszletes nzettbla 90
sszegz fggvnyek 40
sszes termk 90
Roy Harvey 63
S,Sz
Scott Gammans 18
SELECT a SELECT utastsban 104
Paradox 49
patk 78
Paul Dong 86
self-join 31
Pepperoni 121
SIGNO fggvny 70
SIGN(ABS(fn)) 70
PICTURE 33
piltk 64
PL/I 1 7 , 3 3
skalris fggvnyek 83
Trgymutat
Skip Lees 52
szmolgpes karra 83
Software AG 90
szlsrtk-fggvnyek 38
Sorin Shtirbu 37
szemlyzet 144
sorltrehoz fggvnyek 71
szinusz 83
sorszmok 20
szobafoglals 18
SQL felsfokon 2
szkvek 9
SQL Hotel 18
szvegllandk 148
SQL3
83
SQL-89
SQL-92
T,Ty
tbla elsdleges kulcsa 115
tblk ltrehozsa 3
SQL-92 szabvny 43
tblanevek azonossga 16
SQLBase 144
tblzatkezel 84
Steve Roti 72
tblzatkezelk 5
Steve Tilson 19
SUBSTRINGO 33
tancsadi djazs 99
SUMO 114
SUMO fggvny 72
TEOR 55
SuperCalc 5
telefon 40
teljes karakterlnc 17
Sybase-frum 63, 66
teljestmny 47, 53
Syed Kadir 47
tenyrgp 26
SYSTEM R 78
termelsi kltsgek 97
szabad helyek 26
szabvnyos SQL 78
szabvnyos SQL-89 78
szabvnyos SQL-92 83
teszteredmnyek 63
tzbl egy 69
szmts 83
Tom Bragg 75
szmtsi nyelvek 83
tmb 70
SQL-fejtrk
trl lekrdezs 8
zleti v 4
trigger 121
zleti hnap 4
TRIMO 17
u,
V
valdi rszhalmaz 78
dltulajdonos 65
vsrlsi srsg 88
vg-esemny 13
jranormalizls 2
VTEW2
lhelyszakaszok 128
UNION utasts 45
UNIQUE zradk 53
UPDATE lekrdezs 8
UPDATE utasts 16
Y
Yogesh Chacha 24