SQL deel 2
-
Upload
katrien-verbert -
Category
Technology
-
view
1.540 -
download
3
description
Transcript of SQL deel 2
SQL – deel 2
Katrien Verbert [email protected]
SQL
• vorige week: basisconcepten • vandaag: geavanceerde concepten, demo MS Access 2010
2
• Basisvorm van een vraag (query):
• vgl. met relationele algebra: – SELECT projectie – FROM carthesisch product – WHERE selectie
queries in SQL
SELECT <a$ributen lijst> FROM <tabellen lijst> WHERE <condi3es> ;
3
voorbeeld
• Q_0: geef de geboortedatum en het adres van werknemer John B. Smith
Bdate Address ---------- ------------------------ 1965-01-09 731 Fondren, Houston, TX
SELECT Bdate, Address FROM EMPLOYEE WHERE Fname='John' AND Minit='B' AND Lname='Smith’ ;
• Q1B: geef naam en adres van alle werknemers die voor het "research" departement werken
SELECT E.Fname, E.Lname, E.Address FROM EMPLOYEE E, DEPARTMENT D WHERE D.Dname = 'Research' AND D.Dnumber = E.Dno ;
5
geneste queries
• geneste queries – sommige queries vereisen ophalen van bestaande waarden en
het gebruik ervan in voorwaarden; – dat kan dikwijls op eenvoudige wijze geformuleerd worden met
geneste queries.
• IN operator in conditie : – test of tupel ∈ verzameling – verzameling kan zelf door SQL-query bekomen zijn
• → geneste queries
6
SELECT DISTINCT Pnumber FROM PROJECT WHERE Pnumber IN
(SELECT Pnumber FROM PROJECT, DEPARTMENT, EMPLOYEE WHERE Dnum = Dnumber AND Mgr_ssn = Ssn AND Lname = 'Smith') OR Pnumber IN
(SELECT Pno FROM WORKS_ON, EMPLOYEE WHERE Essn = Ssn AND Lname = 'Smith') ;
voorbeeld
– Q 4A: geef alle projecten waarbij Smith betrokken is als manager van het controlerend departement of waaraan hij meewerkt
7
Geef namen van departementen die zich bevinden in België.
8
select ?
from ? where ?
9
SELECT dname
FROM department d, dept_loca3ons l WHERE d.dnumber=l.dnumber and l.dloca3on=‘België’
SELECT dname
FROM department d WHERE d.dnumber in (SELECT l.dnumber
FROM dept_loca3ons WHERE l.dloca3on=‘België’)
SELECT Fname, Lname FROM EMPLOYEE WHERE ( ( SELECT Pno FROM WORKS_ON WHERE Ssn = Essn ) CONTAINS ( SELECT Pnumber FROM PROJECT WHERE Dnum = 5) ) ;
CONTAINS
• CONTAINS: "... heeft als deelverzameling ... " • vgl. met deling
– vb: geef de naam van elke werknemer die werkt op alle projecten gecontroleerd door departement nummer 5
10
in oorspronkelijk system R, later meestal niet geïmplementeerd in meeste versies van SQL
oefening: find the names of sailors who have reserved all boats
Reserves
Sailors
Boats
Relationele algebra temp←πsid,bid(Reserves)/πbid(Boats) result←πsname(temp*sailors)
select ?
from ? where ?
oefening: find the names of sailors who have reserved all boats
Reserves
Sailors
Boats
Relationele algebra temp←πsid,bid(Reserves)/πbid(Boats) result←πsname(temp*sailors)
SELECT sname
FROM sailors s WHERE ((SELECT bid
FROM reserves r WHERE r.sid=s.sid)
CONTAINS
(SELECT bid FROM boats))
SELECT E.Fname, E.Lname FROM EMPLOYEE AS E WHERE EXISTS (SELECT * FROM DEPENDENT WHERE E.Ssn = Essn AND E.Fname = Dependent_name) ;
EXISTS functie in SQL
• controleert of verzameling leeg is of niet • geeft TRUE indien er ten minste één element is, zoniet
FALSE
– Q 16 B: geef de naam van elke werknemer die een persoon ten laste heeft met dezelfde voornaam als de werknemer
13
NOT EXISTS
• geeft TRUE als de verzameling leeg is
• Q 6: geef de namen van de werknemers die geen personen ten laste hebben
SELECT E.Fname, E.Lname FROM EMPLOYEE AS E WHERE NOT EXISTS (SELECT * FROM DEPENDENT WHERE E.Ssn = Essn) ;
14
SELECT Fname, Lname FROM EMPLOYEE WHERE EXISTS ( SELECT * FROM DEPENDENT WHERE Ssn = Essn) AND EXISTS ( SELECT * FROM DEPARTMENT WHERE Ssn = Mgr_ssn) ;
Kan dit ook met 1 geneste query / zonder geneste query?
– Q 7: Geef de namen van de managers die tenminste één persoon ten laste hebben
15
SELECT Fname, Lname FROM EMPLOYEE E WHERE NOT EXISTS (SELECT * FROM WORKS_ON B WHERE B.Pno IN (SELECT Pnumber FROM PROJECT WHERE Dnum = 5) AND NOT EXISTS (SELECT * FROM WORKS_ON C WHERE C.Essn = E.Ssn AND C.Pno = B.Pno) ) ;
• CONTAINS kan ook herschreven worden met NOT EXISTS • Q 3 B herformulering:
– geef alle werknemers waarvoor er geen project bestaat gecontroleerd door departement 5 waarop de werknemer niet werkt
NOT EXISTS
oefening: find the names of sailors who have reserved all boats SELECT sname
FROM sailors s WHERE ((SELECT bid FROM reserves r WHERE r.sid=s.sid)
CONTAINS (SELECT bid FROM boats))
Hoe met NOT EXISTS i.p.v. CONTAINS? SELECT sname
FROM sailors s WHERE NOT EXISTS ( SELECT bid
FROM boats b WHERE NOT EXISTS ( SELECT bid
FROM reserves
WHERE r.sid=s.sid and b.bid = r.bid))
SELECT DISTINCT Essn FROM WORKS_ON WHERE Pno IN (1,2,3) ;
expliciete verzamelingen
• verzameling constanten : – vb. (1,2,3)
• zoek de social security numbers of alle werknemers die werken op projecten nummer 1, 2 of 3
18
SELECT E.Lname AS Employee_name S.Lname AS Supervisor_Name FROM EMPLOYEE AS E, EMPLOYEE AS S WHERE E.Super_ssn = S.Ssn ;
hernoeming van attributen en tabellen met AS • Q 8 A
– geef de familienaam van elke werknemer met de familienaam van zijn/haar supervisor
19
joins
• JOIN operaties kunnen expliciet opgegeven worden – verhoogt de duidelijkheid – join condities gescheiden van selectiecondities
• FROM <tabel1> <jointype> <tabel2> ON <conditie> – inwendige join: [ INNER ] JOIN – uitwendig: { LEFT | RIGHT | FULL } [ OUTER ] JOIN – natuurlijke : NATURAL JOIN
20
voorbeeld
• Q 1 A – geef naam en adres van alle werknemers die voor het
“Research” departement werken
SELECT Fname, Lname, Address FROM (EMPLOYEE JOIN DEPARTMENT ON Dno = Dnumber) WHERE Dname = 'Research’ ;
SELECT Fname, Lname, Address FROM ( EMPLOYEE NATURAL JOIN ( DEPARTMENT AS DEPT (Dname, Dno, Mssn, Msdate) ) ) WHERE Dname = 'Research’ ;
21
voorbeeld
• Q 8 B – geef de familienaam van elke werknemer met de familienaam van zijn/
haar supervisor
SELECT E.Lname AS Employee_name, S.Lname AS Supervisor_name FROM (EMPLOYEE AS E LEFT OUTER JOIN EMPLOYEE AS S ON E.Super_ssn = S.Ssn) ;
22
SELECT SUM(Salary), MAX(Salary), MIN(Salary), AVG(Salary) FROM EMPLOYEE;
aggregaatfuncties
• Ingebouwde functies: – COUNT, SUM, MAX, MIN, AVG
• voorbeeld: zoek som, maximum, minimum en gemiddelde van alle salarissen
23
SELECT SUM(Salary), MAX(Salary), MIN(Salary), AVG(Salary) FROM (EMPLOYEE JOIN DEPARTMENT ON Dno = Dnumber) WHERE DNAME = 'Research’ ;
– Q 20 • zoek som, maximum, minimum, gemiddelde, van de salarissen van alle
werknemers uit het 'Research' departement
aggregaatfuncties
24
• bepaal totaal aantal werknemers
• bepaal aantal werknemers in departement 'Research’
• tel het aantal verschillende waarden voor salaris
SELECT COUNT(*) FROM EMPLOYEE ;
SELECT COUNT(*) FROM EMPLOYEE, DEPARTMENT WHERE Dno = Dnumber AND Dname = 'Research’ ;
SELECT COUNT (DISTINCT Salary) FROM EMPLOYEE ;
aggregaatfuncties
25
SELECT Lname, Fname FROM EMPLOYEE WHERE ( SELECT COUNT(*) FROM DEPENDENT WHERE Ssn = Essn ) >= 2 ;
aggregaatfuncties
– gebruik binnen WHERE (voor geneste queries): – voorbeeld: geef alle werknemers die minstens 2 personen ten
laste hebben
26
SELECT DNO, COUNT(*), AVG(Salary) FROM EMPLOYEE GROUP BY DNO ;
groepering
• Groeperen van tupels : GROUP BY – aggregaatfuncties worden voor elke groep afzonderlijk toegepast
• voorbeeld: geef voor elk departement het nummer, het aantal werknemers en het gemiddelde salaris
27
• geef voor elk project nr, naam en aantal mensen die eraan werken
• .. enkel voor die projecten waar meer dan 2 mensen aan werken : met HAVING
SELECT Pnumber, Pname, COUNT(*) FROM PROJECT, WORKS_ON WHERE Pnumber = Pno GROUP BY Pnumber, Pname ;
SELECT Pnumber, Pname, COUNT(*) FROM PROJECT, WORKS_ON WHERE Pnumber = Pno GROUP BY Pnumber, Pname HAVING COUNT(*) > 2 ;
28
SELECT Pnumber, Pname, COUNT(*) FROM PROJECT, WORKS_ON, EMPLOYEE WHERE Pnumber = Pno AND Ssn = Essn
AND Dno = 5 GROUP BY Pnumber, Pname ;
• geef voor elk project, het projectnummer, de projectnaam, en het aantal werknemers van departement 5 die op dat project werken
29
SELECT Dname, COUNT(*) FROM DEPARTMENT, EMPLOYEE WHERE Dnumber = Dno AND Salary > 40 000 GROUP BY Dname HAVING COUNT(*) > 5 ;
oppassen met condities
• WHERE selecteert tupels vóór groepering • HAVING selecteert achteraf groepen • voorbeeld:
– geef voor elk departement met minstens 5 werknemers, de naam van het departement, het totaal aantal werknemers met salaris > 40 000 in dat departement
– Foute formulering: (wat is er fout aan?)
SELECT Dname, COUNT(*) FROM DEPARTMENT, EMPLOYEE WHERE Dnumber = Dno AND Salary > 40 000 AND Dno IN (SELECT Dno FROM EMPLOYEE GROUP BY Dno HAVING COUNT(*) > 5) GROUP BY Dname ;
• Correcte formulering: – Geef voor elk departement met minstens 5 werknemers het
totaal aantal werknemers met salaris > 40 000 in dat departement
31
algemene vorm van SQL-queries
– SELECT: op te halen attributen / functies – FROM: benodigde tabellen – WHERE: voorwaarden op tupels – GROUP BY: groepering (voor aggregaatfuncties) – HAVING: voorwaarden op gevormde groepen – ORDER: volgorde voor tonen van resultaat
SELECT < a$ributen‐ en func3e‐lijst > FROM < tabellenlijst > [ WHERE < voorwaarde > ] [ GROUP BY < groeperingsa$ributen > ] [ HAVING < groepvoorwaarde > ] [ ORDER BY < a$ributenlijst > ] ;
32
aanpassingen maken in SQL
• Toevoegen: INSERT • Weglaten: DELETE • Wijzigen: UPDATE
33
INSERT INTO EMPLOYEE VALUES ('Richard', 'K', 'Marini', '653298653', ‘1962‐12‐30', '98 Oak Forest, Katy', TX', 'M', 37000, '987654321', 4) ;
INSERT INTO EMPLOYEE (Fname, Lname, Ssn) VALUES ('Richard', 'Marini', '653298653') ;
toevoegen
• INSERT commando • verschillende vormen
– zonder expliciete vermelding van attributen: • volgorde respecteren
– met expliciete vermelding van attributen: • nulls en defaults kunnen weggelaten worden
34
CREATE TABLE DEPTS_INFO ( Dept_name VARCHAR(15),
No_of_emps INTEGER, Total_sal INTEGER );
INSERT INTO DEPTS_INFO (Dept_name,No_of_emps,Total_sal) SELECT Dname, COUNT(*), SUM(Salary)
FROM ( DEPARTMENT JOIN EMPLOYEE ON Dnumber = Dno )
GROUP BY Dname ;
In dit voorbeeld niet zo'n goed idee redundantie + mogelijk verlies van integriteit beter : view definiëren (zie later)
Meerdere tupels tegelijk toevoegen
• vaak meteen na creatie van tabel, laden van resultaat van een query
35
DELETE FROM EMPLOYEE ;
DELETE FROM EMPLOYEE WHERE Ssn =‘123456789' ;
DELETE FROM EMPLOYEE WHERE Dno IN (SELECT Dnumber FROM DEPARTMENT WHERE Dname = 'Research') ;
weglaten van tupels • DELETE FROM <tabel> WHERE <conditie>
– alle tupels die aan conditie voldoen worden weggelaten – geen WHERE deel: alle tupels weg
• ! tabel verdwijnt niet, wordt enkel leeg • tabel kan weggelaten worden met DROP TABLE
DELETE FROM EMPLOYEE WHERE Lname =‘Brown' ;
36
UPDATE PROJECT SET Ploca3on = 'Bellaire', Dnum = 5 WHERE Pnumber = 10 ;
UPDATE EMPLOYEE SET Salary = Salary * 1.1 WHERE Dno IN (SELECT Dnumber FROM DEPARTMENT WHERE Dname = 'Research') ;
wijzigen van tupels
• UPDATE <tabel> SET { < attr > = < expr > , … } WHERE <conditie>
• selecteer te wijzigen tupels met WHERE-conditie • ken voor die tupels nieuwe waarden aan attributen toe: in SET deel
37
views in SQL
• “view" = afgeleide relatie – tupels worden niet expliciet opgeslagen – maar worden berekend uit andere relaties (= de definiërende
tabellen van de view)
38
• sytax CREATE VIEW <viewname> [ < lijst van attribuutnamen> ] AS <query>
CREATE VIEW WORKS_ON1 AS SELECT Fname, Lname, Pname, Hours FROM EMPLOYEE, PROJECT, WORKS_ON WHERE Ssn = Essn AND Pno = Pnumber ;
CREATE VIEW DEPT_INFO(Dept_name,No_of_emps,Total_sal) AS SELECT Dname, COUNT(*), SUM(Salary) FROM DEPARTMENT, EMPLOYEE WHERE Dnumber = Dno GROUP BY Dname ;
specificeren van een view
V1
39
gebruik van views
• queries op view: zoals bij gewone tabellen
• Voordelen van views?
SELECT Fname, Lname FROM WORKS_ON1 WHERE Pname = ‘ProductX’ ;
40
• eenvoudiger formulering van queries • beveiligingsmechanisme
• gebruiker zicht op deel van gegevensbank geven • vs. nieuwe tabel (cf. DEPT_INFO):
• geen redundantie • steeds up-to-date
weglaten van view
• DROP VIEW (cf. gewone tabel) – voorbeeld:
– geen verwijdering van tupels
DROP VIEW WORKS_ON1;
41
implementatie van views
• twee benaderingen: – query modification:
• query op view wordt omgevormd tot query op onderliggende tabellen; • nadeel: kan tot complexe en tijdsintensieve queries leiden
– view materialization: • tijdelijke creatie van de afgeleide (view) tabel wanneer ze voor het eerst in
een query gebruikt wordt; • vereist ‘incremental update’: aanpassing van de afgeleide tabel wanneer
basistabellen gewijzigd worden; • afgeleide tabel wordt automatisch weggelaten als ze een tijd niet meer
gebruikt wordt
42
voorbeeld van query modification
– de query QV1 op view WORKS_ON1
– wordt omgevormd tot
SELECT Fname, Lname FROM WORKS_ON1 WHERE Pname = ‘ProductX’ ;
SELECT Fname, Lname FROM EMPLOYEE, PROJECT, WORKS_ON WHERE Ssn = Essn AND Pno = Pnumber
AND Pname = ‘ProductX’ ;
43
wijzigen van view
• view is afgeleid uit andere relaties • ⇒ wijziging moet doorgegeven worden aan andere relaties • niet steeds mogelijk op eenduidige manier!
44
wijzigen van view
• View ← 1 basisrelatie: – aanpassing aan view → aanpassing aan basisrelatie
• View ← join van meerdere basisrelaties: – welke relaties aanpassen?
45
UPDATE WORKS_ON1 SET Pname = 'ProductY' WHERE Lname = 'Smith' AND Fname = 'John' AND Pname = 'ProductX’ ;
voorbeeld
• Wijzig PNAME van John Smith in WORKS_ON1 van 'ProductX' naar 'ProductY’
• Hoe de wijziging van productnaam doorgeven aan basisrelaties? – Is het project van naam veranderd? – Of werkt John Smith nu aan een ander project, nl. ProductY
i.p.v. ProductX ?
46
UPDATE PROJECT SET Pname = 'ProductY' WHERE Pname = 'ProductX’ ;
UPDATE WORKS_ON SET Pno = (SELECT Pnumber FROM PROJECT WHERE Name = 'ProductY') WHERE Essn = (SELECT Ssn FROM EMPLOYEE WHERE Lname = 'Smith' AND Fname = 'John') AND PNO IN (SELECT Pnumber FROM PROJECT WHERE Pname = 'ProductX') ;
UPDATE DEPT_INFO SET TOTAL_SAL=100000 WHERE DNAME='Research’ ;
sommige aanpassingen zijn zinloos:
47
wijzigen van views: algemeen
• een view afgeleid uit 1 tabel kan aangepast worden als de view een primaire sleutel of kandidaatsleutel van die tabel bevat (→ te wijzigen tupel is eenduidig bepaald)
• een view afgeleid uit meerdere tabellen is meestal niet aanpasbaar – indien meerdere aanpassingen mogelijk zijn, moet er een
procedure zijn om hieruit te kiezen, b.v.: • gebruiker vragen een keuze te maken
– DBMS meest waarschijnlijke laten kiezen • resultaten van aggregaatfuncties kunnen niet
aangepast worden
48
ASSERTIONS
ter herinnering
• restricties op tabellen • restricties op attribuutwaarden
50
restricties op tabellen
• primaire sleutel: PRIMARY KEY <attrlist> • alternatieve sleutel: UNIQUE <attrlist>
worden nagekeken bij toevoegen of wijzigen van tupels
• verwijssleutel: FOREIGN KEY <attrlist> REFERENCES <table><attrlist>
wordt nagekeken bij toevoegen of wijzigen van tupels in tabel wordt nagekeken bij verwijderen of wijzigen van tupels in verwijzende tabel
51
referentiële integriteit
• Dno in EMPLOYEE verwijst altijd naar een bestaand dnumber in DEPARTMENT
primary key foreign key
53
referentiële integriteit
• Dno in EMPLOYEE verwijst altijd naar een bestaand dnumber in DEPARTMENT
primary key foreign key
6 6 6
restricties op attribuut
• NOT NULL (automatisch voor primaire sleutels) • DEFAULT <value> • CHECK (voorwaarde)
Dnumber INT NOT NULL CHECK (Dnumber > 0 AND Dnumber < 21);
55
worden nagekeken bij toevoegen of wijzigen van attribuutwaarden
algemene restricties specificeren
• andere restricties dan sleutel-, entiteits- en referentiële restricties opgeven: ASSERTION
• algemene vorm:
CREATE ASSERTION <name> CHECK <cond>
56
CREATE ASSERTION SALARY_CONSTRAINT CHECK ( NOT EXISTS ( SELECT * FROM EMPLOYEE E, EMPLOYEE M, DEPARTMENT D WHERE E.Salary > M.Salary AND E.Dno = D.Dnumber AND D.Mgr_ssn = M.Ssn) ) ;
voorbeeld
– salaris van werknemer <= salaris van manager van dept. waarvoor werknemer werkt
57
werking • bij creatie van een ASSERTION, wordt gecontroleerd of eraan voldaan is • elke latere wijziging in de gegevensbank:
– slechts toegelaten indien aan de ASSERTION voldaan is – dit kan veel extra werk vereisen!
• Voorbeeld: er moeten minstens drie werknemers per afdeling zijn.
CREATE ASSERTION NIET_MINDER_DAN_3 AS CHECK (NOT EXISTS (SELECT e1.DNO FROM (SELECT DISTINCT DNO FROM EMPLOYEE e1 WHERE 3 > (SELECT count(*) FROM EMPLOYEE e2 WHERE e2.DNO = e1.DNO)));
58
CHECK-clausule
• kan ook bij – attribuut - definitie – CREATE DOMAIN gebruikt worden
• → domeinrestricties • voorbeeld:
– departementsnummer kan slechts een gehele waarde tussen 1 en 20 zijn:
CREATE DOMAIN D_NUM AS INTEGER CHECK (D_NUM > 0 AND D_NUM < 21) ;
DNUMBER INT NOT NULL CHECK (DNUMBER > 0 AND DNUMBER < 21);
59
• CHECK – wordt slechts gecontroleerd bij toevoegen of aanpassen van tupels,
slaat op attributen of tupels – kan dus efficiënter geïmplementeerd worden
• ASSERTION – is meer algemeen
60
andere mogelijkheden
• CREATE TRIGGER
• hierbij wordt de te nemen actie opgegeven wanneer niet aan de voorwaarde voldaan is
61
TRIGGERS
triggers
• een trigger bestaat uit 3 delen: • een event (bv. update van een attribuut) • een voorwaarde (bv. een query die nagekeken wordt) • een actie (bv. delete, update, insert)
• syntax
CREATE TRIGGER <name> { BEFORE | AFTER } <event> ON <table> FOR EACH ROW WHEN (<cond>)
<ac3on>
63
voorbeeld
CREATE TRIGGER TotalSal1 AFTER INSERT ON EMPLOYEE FOR EACH ROW WHEN (NEW.DNO IS NOT NULL)
UPDATE DEPARTMENT SET TOTAL_SAL=TOTAL_SAL + NEW.SALARY WHERE DNO=NEW.DNO
64
elementen van triggers
• timing van uitvoering van de actie – before – after – instead of
• actie kan verwijzen naar oude of nieuwe toestand van de gegevensbank
• conditie wordt gespecificeerd in WHEN clausule
65