SQL Språk for Skjemadefinisjon Spørringar Database-oppdateringar Svært høgnivå: i prinsippet skriv ein kva ein vil ha som resultat, utan å spesifisere korleis Sterk grad av optimalisering effektivt Skjemadefinisjon og datainnsetting i SQL CREATE TABLE Fag( fagkode CHAR(6) PRIMARY KEY, fagnavn VARCHAR(40), eksamensdato DATE ); INSERT INTO Avdelingar VALUES('Adm','Innherredsvn. 34','3'); Meir detaljar seinare om: Skjemadefinering/modifisering Datainnsetting/modifisering 1 2 SELECT-FROM-WHERE Semantikk bak ein-relasjons-spørring Basisuttrykk: SELECT sett med attributtar FROM ein eller fleire tabellar WHERE vilkår for tuplar; SELECT namn,adr WHERE tavdnamn= ; 1. Start med relasjonen i FROM-delen. 2. Utfør (bag) σ med vilkåret i WHERE-delen. 3. Utfør (utvida/bag) π med attributtane I SELECT-delen. Finne namn og adresse på tilsette som arbeider i -avdelinga som nettopp vist: 3 4 1
Gjennomgangseksempel: Firmadatabasen Tilsette(persnr, namn, adr, løn, tavdnamn) Avdelingar(avdnamn,adr,leiar) Prosjekt(prosjnamn,avdnamn) ArbeiderPå(persnr,prosjnamn,timar) Innhald i Tilsette-relasjonen persnr namn adr lonn tavdnamn -------------+--------+------------------+---------+---------- 3 Kari Ingeman Torpsv 350000 Adm 12 Espen Bynesvn 3 180000 4 Petter Sem Sælandsv. 7 600000 2 Ola Møllenberg 200000 10 Sofie Prinsensgt. 12 50000 Salg 6 Erik Moholt Alle 13 700000 Adm 7 Kjetil Ila 120000 5 Anne Sandgt. 13 800000 Adm 1 Per Ila 400000 Salg 8 Jon Munkegt. 3 340000 9 Ida Ila 120000 Salg 11 Pål Elgesetergt. 133 1200000 5 6 Eksempel Finne namn og adresse på tilsette som arbeider i -avdelinga: SELECT namn,adr WHERE tavdnamn= ; namn adr --------+------------------ Espen Bynesvn 3 Petter Sem Sælandsv. 7 Ola Møllenberg Kjetil Ila Jon Munkegt. 3 Pål Elgesetergt. 133 Eksempel: * i SELECT Finne tilsette som arbeider i -avdelinga: SELECT * WHERE tavdnamn= ; persnr namn adr lonn tavdnamn ---------+--------+------------------+---------+-------- 12 Espen Bynesvn 3 180000 4 Petter Sem Sælandsv. 7 600000 2 Ola Møllenberg 200000 7 Kjetil Ila 120000 8 Jon Munkegt. 3 340000 11 Pål Elgesetergt. 133 1200000 7 8 2
Oppgåve Finn alle namn & avdeling for alle tilsette med meir enn 400000 i løn! SELECT namn,tavdnamn FROM tilsette WHERE lonn > 400000; namn tavdnamn --------+------------- Petter Erik Adm Anne Adm Pål Eksempel på endring av attributtnamn SELECT namn AS tilsettnamn,adr WHERE tavdnamn= ; tilsettnamn adr ---------------+------------------ Espen Bynesvn 3 Petter Sem Sælandsv. 7 Ola Møllenberg Kjetil Ila Jon Munkegt. 3 Pål Elgesetergt. 133 9 10 Uttrykk i SELECT-delen SELECT namn, lonn/7.02 AS dollarlonn, dollar AS valuta WHERE tavdnamn= ; namn dollarlonn valuta --------+--------------------+-------- Espen 25641.025641025641 dollar Petter 85470.085470085470 dollar Ola 28490.028490028490 dollar Kjetil 17094.017094017094 dollar Jon 48433.048433048433 dollar Pål 170940.17094017094 dollar Sortering Tilsette som tener over 300000, sortert på avdeling: SELECT namn,tavdnamn WHERE lonn > 300000 ORDER BY tavdnamn; Kan også sortere på meir enn ein attributt, t.d. ORDER BY etternavn,fornavn; Og minkande: ORDER BY namn DESC; namn tavdnamn -------+-------- Anne Adm Erik Adm Kari Adm Pål Petter Jon Per Salg 11 12 3
Substreng-samanlikningar: LIKE SELECT FROM WHERE attrib LIKE streng Vilkårleg teikn: _ ( underscore ) Vilkårleg tal på vilkårlege teikn: % SELECT FROM WHERE attrib LIKE _jetil% Liste over den/dei som bur i Prinsensgate: SELECT namn,adr WHERE adr LIKE 'Prinsensg%'; namn adr ------+---------------- Sofie Prinsensgt. 12 13 Eksempel-instans Tilsette: persnr namn adr lonn tavdnamn -----------+--------+------------------+--------+-------- 3 Kari Ingeman Torpsv 350000 Adm 12 Espen Bynesvn 3 180000 4 Petter Sem Sælandsv. 7 600000 2 Ola Møllenberg 200000 10 Sofie Prinsensgt. 12 50000 Salg 6 Erik Moholt Alle 13 700000 Adm 7 Kjetil Ila 120000 5 Anne Sandgt. 13 800000 Adm 1 Per Ila 400000 Salg 8 Jon Munkegt. 3 340000 9 Ida Ila 120000 Salg 11 Pål Elgesetergt. 133 1200000 Avdelingar: avdnamn adr leiar ----------+------------------+------------- Sandgata 11 7 Salg Nordre gate 1 9 Adm Innherredsvn. 34 3 14 Join-eksempel Utgangspunkt i firmadatabasen To av relasjonane i denne er: Tilsette(persnr, namn, adr, løn, tavdnamn) Avdelingar(avdnamn,adr,leiar) Oppgåve: Finne løna til kvar av leiarane i firmaet. Resultatet skal vere ein relasjon med skjemaet LeiarLøn(namn,løn) SELECT namn,lonn, Avdelingar WHERE Tilsette.persnr=Avdelingar.leiar; namn lonn --------+-------- Kari 350000 Kjetil 120000 Ida 120000 15 Alias SELECT namn,lonn t, Avdelingar a WHERE t.persnr=a.leiar; namn lonn --------+-------- Kari 350000 Kjetil 120000 Ida 120000 16 4
Semantikk bak fleir-relasjons-spørjing 1. Start med (kartesisk) produkt av alle relasjonane i FROM-delen. 2. Utfør (bag) σ med vilkåret i WHERE-delen. 3. Utfør (utvida/bag) π med attributtane i SELECT-delen. Finne løna til kvar av leiarane i firmaet som nettopp vist: Oppgåve Gitt relasjonane: Fag(fagkode,fagnamn,forelesarpersnr) Forelesar(persnr,namn,emailadr) Finn email-adressa til forelesaren i IT1607! Løysing: SELECT emailadr FROM Fag, Forelesar WHERE Fag.forelesarpersnr=Forelesar.persnr AND Fag.fagkode= IT1607 ; 17 18 NULL (1) Kan brukast i staden for verdi (Fag,Forelesar,Eksamensdato) ( IT1607, Kjetil, NULL) Kan bety: Ukjend verdi, t.d. ukjend fødselsdato Ingen verdi, t.d. ektefelle-atributt for ugift person Kan også verte produsert av SQL, t.d. ved OUTER JOIN NULL (2) Resultat av aritmetisk operator og NULL: NULL Teste for NULL: Må bruke IS NULL Samanlikning av NULL og annan verdi: UNKNOWN 3-verdi-logikk: TRUE/FALSE/UNKNOWN 19 20 5
Aggregeringsfunksjonar Finn max/min/gjennsomsnittsløn for alle tilsette: SELECT MAX(lonn),MIN(lonn),AVG(lonn) ; max min avg ---------+-------+-------------------- 1200000 50000 421666.66666666667 Tal på tilsette: SELECT COUNT(*) ; Oppgåve: Gjennomsnittsløn for tilsette i Adm? lonn --------- 350000 180000 600000 200000 50000 700000 120000 800000 400000 340000 120000 1200000 Gruppering: GROUP BY For kvar avdeling, finn gjennomsnittsløn og tal på tilsette: SELECT tavdnamn,count(*),avg(lonn) GROUP BY tavdnamn; tavdnamn count avg ----------+-------+-------------------- Adm 3 616666.66666666667 6 440000.00000000000 Salg 3 190000.00000000000 (3 rows) 21 22 Gruppering (2): HAVING Finn alle avdelingar med gjennomsnittsløn høgre enn 400000: SELECT tavdnamn,avg(lonn) GROUP BY tavdnamn HAVING AVG(lonn)>400000; tavdnamn avg ----------+------------------ Adm 616666.66666666667 440000.00000000000 HAVING vert brukt på kvar gruppe, og kun grupper som oppfyller vilkåret er med Oppgåve Gå utifrå følgjande relasjonsskjema (primærnøklar er understreka, attributtar med same namn som ein annan tabell sin primærnøkkel er framandnøklar): Bil(regnummer,farge,type,årsmodell,eigarnamn) Type(type,motorkraft) BilEigar(eigarnamn,eigaradresse,eigartelefon) Verkstad(verkstadnamn,verkstadadresse,verkstadtelefon) Reparasjon(verkstadnamn,regnummer,tidspunkt) Gje SQL-uttrykk for å finne: 1. tal på reparasjonar for kvar verkstad 2. telefonnummer til alle bileigarar som har hatt blå bil til reparasjon 23 24 6
Tabellar som sett i SQL SELECT tavdnamn ; SELECT DISTINCT tavdnamn ; tavdnamn --------- Adm Salg tavdnamn --------- Adm Salg Adm Adm Salg Salg Settoperasjonar i SQL UNION INTERSECT EXCEPT (Oracle: MINUS) Personnummer til alle tilsette som ikkje er leiarar: (SELECT persnr ) EXCEPT (SELECT leiar FROM Avdelingar); NB! Default resultat av settoperasjon er eit sett! Ønskjer ein bag som resultat: UNION ALL/INTERSECT ALL/EXCEPT ALL persnr ----------- 1 10 11 12 2 4 5 6 8 (9 rows) 25 26 Nøsta spørjingar (nested queries) Resultat frå ei SELECT-FROM-WHERE-spørjing kan verte brukt i WHERE-delen av ei anna spørjing Enklaste tilfelle: sub-spørjing returnerer ein unary tuppel: SELECT a,b FROM R WHERE vilkår AND c = (SELECT attrib FROM S WHERE vilkår); Nøsta spørjingar: Eksempel BrusPrisar(butikk,brus,pris) Vil finne alle stadar som sel Pepsi Cola til same pris som Rema sel Coca Cola 27 28 7
IN-operatoren Brukt i uttrykket i WHERE-delen tuppel IN relasjon er TRUE kun om tuppel er ein av tuplane i relasjon Eksempeldatabase: Vin(namn,produsent,land) Liker(person,vinnamn) Finn namn og produsent av vinar som Kjetil liker! Vindatabase: eksempel-instans namn produsent land ---------------------+---------------+--------- Ardanza Rioja Alta Spania Alberdi Rioja Alta Spania Gran Reserva 904 Rioja Alta Spania Chateau Musar Chateau Musar Libanon Hochar Père et Fils Chateau Musar Libanon Ksara Ksara Libanon Polets Rødvin Arcus Diverse person vinnamn --------+--------------- Kjetil Ardanza Kjetil Chateau Musar 29 30 EXISTS-operatoren EXISTS(relasjon) er TRUE berre om relasjon inneheld tuplar (minst ein) Finne vinar frå leverandørar med berre ein vin For kvar vin, sjekke at det ikkje eksisterer andre vinar frå same produsent Oppgåve Produkt(produsent,modell,type) PC(modell,hastigheit,ram,pris) Laptop(modell,hastigheit,ram,skjerm,pris) Skrivar(modell,farge,type,pris) Finn produsentar av PC ar med prosessorhastigheit på 2600 eller meir, bruk minst ei sub-spørjing i svaret Skriv spørjinga på ein annan måte, men framleis med minst ei sub-spørjing i svaret 31 32 8
Svar SELECT DISTINCT produsent FROM Produkt WHERE modell IN (SELECT modell FROM PC WHERE hastigheit >= 2600); SELECT DISTINCT produsent FROM Produkt WHERE EXISTS (SELECT * FROM PC WHERE hastigheit >= 2600 AND Produkt.modell = modell); Kvantifikatorar: ANY og ALL Finn kvar dyraste brus vert seld BrusPrisar(butikk,brus,pris) SELECT butikk FROM BrusPrisar WHERE pris >= ALL( SELECT pris FROM BrusPrisar); 33 34 Sub-spørjingar i FROM-delen Finn spanske vinar som Kjetil liker SELECT Spanskvin.namn FROM Liker, (SELECT * FROM Vin WHERE land='spania' ) SpanskVin WHERE Liker.vinnamn=SpanskVin.namn AND Liker.person='Kjetil'; JOIN-uttrykk i SQL (1) Kan konstruere relasjonar med variantar av JOIN-operatorar SELECT Vin.namn FROM Liker JOIN Vin ON Liker.vinnamn= Vin.namn WHERE Vin.land='Spania'; 35 36 9
JOIN-uttrykk i SQL (2) Andre variantar: RelR NATURAL JOIN RelS RelR LEFT OUTER JOIN RelS ON <vilkår> RelR RIGHT OUTER JOIN RelS ON <vilkår> RelR FULL OUTER JOIN RelS ON <vilkår> RelR NATURAL LEFT/RIGHT/FULL OUTER JOIN RelR Databaseinnsetting (1) INSERT INTO R(A 1,,A n ) VALUES (v 1,,v n ); INSERT INTO Vin VALUES('Ardanza','Rioja Alta','Spania'); INSERT INTO Vin VALUES('Chateau Musar','Chateau Musar','Libanon'); INSERT INTO Liker VALUES('Kjetil','Ardanza'); INSERT INTO Liker VALUES('Kjetil','Chateau Musar'); 37 38 Databaseinnsetting (2) Kan også sette inn resultat frå sub-spørjing Alle spanske vinar inn i ein relasjon SpanskVin(namn,produsent) INSERT INTO SpanskVin(namn,produsent) SELECT namn,produsent FROM Vin WHERE Vin.land='Spania'; Sletting DELETE FROM R WHERE <vilkår> Slette alle spanske vinar: DELETE FROM Vin WHERE Vin.land='Spania'; 39 40 10
Oppdatering Oppdatere delar av tuplar som allereie eksisterer UPDATE R SET <oppdateringsliste> WHERE <vikår> Oppdatere Spania til Spania (EU) : UPDATE Vin SET land=land '(EU)' WHERE land='spania'; 41 Skjemadefinering/modifisering Databaseskjema innheld deklarasjonar av tabellar, indeksar etc. CREATE TABLE Fag( fagkode CHAR(6) PRIMARY KEY, fagnavn VARCHAR(40), eksamensdato DATE ); Andre viktige datatyper: BOOLEAN INT/INTEGER Slette tabell: DROP TABLE Fag; Legge til/fjerne attributt (ofte meir aktuelt): ALTER TABLE Fag ADD Faglærar CHAR(50); ALTER TABLE Fag DROP Faglærar; 42 Indeksar Views Indeks på attributt A gjer det mogleg raskt å finne tuplar som har ein bestemt verdi for A Katalog(etternamn,fornavn,adresse,telefonn ummer) Finne person som har eit visst telefonnummer Dum lagring : Søke gjennom alle tuplane for å finne telefonnummer Med indeks: Hoppe direkte til person/telefonnummer: CREATE INDEX NummerIdx ON Katalog(telefonnummer) Bruk av indeks medfører at oppdatering vert treigare Virtuell tabell (i kontrast til lagra base-tabellar) Definert med utgangspunkt i andre tabellar og views CREATE VIEW SpanskVin AS SELECT namn,produsent FROM Vin WHERE Vin.land='Spania(EU)'; 43 44 11
Aksessere view Kan spørjast akkurat som ein baserelasjon SELECT namn FROM SpanskVin; namn ------------------ Ardanza Alberdi Gran Reserva 904 Kva skjer når eit view vert brukt? Databasesystemet startar med å tolke spørjinga som om view et er basetabell Typisk: til noko som liknar relasjonsalgebra Spørjingar som definerer view brukt i spørjinga vert erstatta med algebraiske ekvivalentar og fletta inn i operator-treet til spørjinga Kan av og til gjere oppdateringar mot view 45 46 Restriksjonar og triggerar Nøklar og framandnøklar Lokale og globale restriksjonar ( constraints ) Triggerar ( triggers ) Framandnøklar og innsetting/oppdatering CREATE TABLE Vin( namn VARCHAR(20) PRIMARY KEY, produsent VARCHAR(20) NOT NULL, land VARCHAR(20) ); CREATE TABLE Liker( person VARCHAR(20), PRIMARY KEY(person,vinnamn), vinnamn VARCHAR(20) REFERENCES Vin(namn) ON DELETE CASCADE ON UPDATE NO ACTION); 47 48 12
Restriksjonar på attributtar og tuplar CREATE TABLE Vin( namn VARCHAR(20) PRIMARY KEY, produsent VARCHAR(20), land VARCHAR(20), pris REAL CHECK (pris < 300) ); Uttrykket i CHECK kan også vere sub-spørjing som returnerer boolsk resultat Også mogleg utanfor tabelldeklarasjon: CREATE ASSERTION namn CHECK ( ); Triggerar Motivasjon: Attributt/tuppel-baserte sjekkar ikkje alltid eigna Assertions ikkje alltid nok effektive Løysing: Triggerar Brukar kan spesifisere når den skal utførast Kan utføre vilkårlege databasemodifiseringar 49 50 Hending-Vilkår-Aksjon-reglar (Event-Condition-Action rules) Hending: typisk databasemodifisering, t.d. INSERT ON Liker Vilkår: Generell SQL-uttrykk med boolsk verdi Aksjon: Vilkårleg SQL-setning CREATE TRIGGER SpanskVinTrig AFTER INSERT ON Vin REFERENCING NEW AS Ny FOR EACH ROW WHEN (Ny.land = 'Spania') BEGIN INSERT INTO SpanskVin VALUES(Ny.vinnamn,Ny.produsent) END; 51 13