Avansert bruk av SQL Avanserte spørringer Valguttrykk Spørring på spørring Unionspørringer Delspørringer, vekselvirkende delspørringer Kvantorer Begrensninger ved SQL Pensum: Kapittel 5 Databaser Leksjon 4: Avansert bruk av SQL - 1
Valguttrykk Kan blant annet brukes for å klassifisere verdiene i en kolonne. SELECT VNr, Betegnelse, CASE WHEN Pris<100 THEN Billig WHEN Pris<=500 THEN Middels ELSE Dyr END AS Prisklasse FROM Vare DBHS sjekker greinene i den rekkefølgen det står! Første betingelse som blir sann gir verdien til hele CASE-uttrykket. MySQL tilbyr en IF-funksjon som man kan nøstes: IF(Pris<100, Billig, IF(Pris<=500, Middels, Dyr )) Databaser Leksjon 4: Avansert bruk av SQL - 2
Databasetabellen Vare VNr Betegnelse Pris Kategori Antall Hylle 90693 Marsipantang 57.00 Konditor 0 B17 44939 Malerskrin, 6 farger 115.00 Hobbymaling 2 B02 15217 Kram tørrfluekorker 32.00 Fiske 213 B42 15211 Tubeflueverktøy 209.00 Fiske 39 B42 33045 Blomkarse 17.50 Blomster 206 E05 55130 Moro med marsipan 598.50 Bøker 140 C20 42615 Gipsform marihøner 106.00 Keramikk 124 B03 SELECT VNr, Betegnelse, CASE WHEN Pris<100 THEN Billig WHEN Pris<=500 THEN Middels ELSE Dyr END AS Prisklasse FROM Vare Databaser Leksjon 4: Avansert bruk av SQL - 3
Databasetabellen Vare VNr Betegnelse Pris Kategori Antall Hylle 90693 Marsipantang 57.00 Konditor 0 B17 44939 Malerskrin, 6 farger 115.00 Hobbymaling 2 B02 15217 Kram tørrfluekorker 32.00 Fiske 213 B42 15211 Tubeflueverktøy 209.00 Fiske 39 B42 33045 Blomkarse 17.50 Blomster 206 E05 55130 Moro med marsipan 598.50 Bøker 140 C20 42615 Gipsform marihøner 106.00 Keramikk 124 B03 Hva med? SELECT VNr, Betegnelse, CASE WHEN Pris<=500 THEN Middels WHEN Pris<100 THEN Billig ELSE Dyr END AS Prisklasse FROM Vare Databaser Leksjon 4: Avansert bruk av SQL - 4
Nullmerker Av og til vi vil erstatte nullmerker med en bestemt verdi. Antar kolonnen Kjønn inneholder verdiene «K» og «M». Hvis vi vil erstatte nullmerker med verdi «U» (ukjent) kan vi bruke funksjonen IFNULL SELECT KNr, Etternavn, IFNULL(Kjønn, U ) FROM Kunde Hva er feil med IF(Kjønn=NULL, U,Kjønn) Hva bør vi bruke isteden av =? Databaser Leksjon 4: Avansert bruk av SQL - 5
Utsnitt (view) Et utsnitt (view) er en «virtuell tabell». Tenk på et utsnitt som en «navngitt spørring». Eksempel: CREATE VIEW DyreVarer AS SELECT * FROM Vare WHERE Pris > 100 Vi kommer tilbake til utsnitt i kapittel 8. Databaser Leksjon 4: Avansert bruk av SQL - 6
Spørring på spørring/utsnitt Problem: Finn antall stillingsbetegnelser. Delproblem 1: Finn stillingsbetegnelsene CREATE VIEW StillingsBetegnelser AS SELECT DISTINCT Stilling FROM Ansatt Delproblem 2: Beregn antallet SELECT COUNT(*) AS Antall FROM StillingsBetegnelser Vi kan bruke navn på utsnitt i FROM. Vi bryter ned et sammensatt problem i to enklere delproblemer! Databaser Leksjon 4: Avansert bruk av SQL - 7
Delspørringer En delspørring er en spørring som forekommer som del av en spørring (hovedspørring), gjerne i en WHERE-betingelse. Finn alle som tjener mer enn gjennomsnittet: SELECT * FROM Ansatt WHERE Lønn > ( SELECT AVG(Lønn) FROM Ansatt ) Delspørringen her må returnere en tabell med nøyaktig èn rad og èn kolonne (for å kunne brukes på høyresiden av > ). Tenk at resultatet av delspørringen «limes inn» i hovedspørringen. Med gjennomsnittslønn 220.000 får vi Lønn>220.000. Hvor mange ganger må DBHS gjennomløpe tabellen Ansatt? Databaser Leksjon 4: Avansert bruk av SQL - 8
Vekselvirkende delspørringer Finn de som tjener mer enn gjennomsnittslønnen innenfor sin stillingskategori: SELECT A1.* FROM Ansatt AS A1 WHERE Lønn > ( SELECT AVG(Lønn) FROM Ansatt AS A2 WHERE A1.Stilling = A2.Stilling ) Sammenlign med spørringen «Finn alle som tjener mer enn gjennomsnittet». Hvor mange ganger må DBHS nå gjennomløpe tabellen Ansatt? Databaser Leksjon 4: Avansert bruk av SQL - 9
Operatorer for delspørringer - IN IN avgjør om en verdi er med i en mengde, og tilsvarer. Kunder med minst en tilhørende ordre: SELECT * FROM Kunde WHERE KNr IN (SELECT KNr FROM Ordre) Hva med WHERE KNr NOT IN (SELECT KNr FROM Ordre)? Vi kan også spørre mot en liste med literaler: SELECT * FROM Vare WHERE KatNr IN (2, 4, 7) Databaser Leksjon 4: Avansert bruk av SQL - 10
Operatorer for delspørringer - ALL og SOME Finn de som tjener mer enn alle sekretærer: SELECT * FROM Ansatt WHERE Lønn > ALL (SELECT Lønn FROM Ansatt WHERE Stilling='Sekretær') Hva om vi skriver SOME i stedet for ALL? Kan vi klare oss uten ALL? Tips: Bruk MAX. Delspørringen her må returnere èn kolonne (som må inneholde beløp). Databaser Leksjon 4: Avansert bruk av SQL - 11
Operatorer for delspørringer - EXISTS Finn ansatte som ikke har deltatt på noen prosjekter: SELECT A.* FROM Ansatt AS A WHERE NOT EXISTS (SELECT * FROM ProsjektDeltakelse AS PD WHERE PD.AnsNr = A.AnsNr) EXISTS sjekker om resultatet er tomt. EXISTS kan av og til erstattes av IN. La delspørringen returnere en liste med ansattnumre. Finn ansatte som har vært med på alle prosjekter. Tips: For ansatt X må det ikke finnes prosjekter som X ikke har deltatt i. Databaser Leksjon 4: Avansert bruk av SQL - 12
Begrensninger ved SQL La Slekt være en tabell med kolonner Person, Mor og Far (som alle inneholder personnr). Lag en spørring som finner mor og far for en bestemt person. Hva med bestemødre og bestefedre? PNr Navn Kjønn Far Mor 1 Lise K 2 4 2 Roar M 3 Arne M 5 4 Oda K 5 Anette K 2 Databaser Leksjon 4: Avansert bruk av SQL - 13
Begrensninger ved SQL Finner samtlige besteforeldre: SELECT S1.PNr, S1.Navn, S1.Far, S1.Mor S2.Far AS Farfar, S2.Mor AS Farmor, S3.Far AS Morfar, S3.Mor AS Mormor FROM Slekt AS S1, Slekt AS S2, Slekt AS S3 WHERE S1.Far = S2.PNr AND S1.Mor = S3.PNr PNr Navn Kjønn Far Mor 1 Lise K 2 4 2 Roar M 3 Arne M 5 4 Oda K 5 Anette K 2 Databaser Leksjon 4: Avansert bruk av SQL - 14
Begrensninger ved SQL La Slekt være en tabell med kolonner Person, Mor og Far (som alle inneholder personnr). Hva med samtlige forfedre for en gitt person? Hvor mange gjennomløp av tabellen medfører spørringene (hvis personnr ikke er ordnet på noe systematisk vis)? Det er vanskelig/umulig å løse denne oppgaven med SQL (avhenger av om DBHS støtter rekursjon). Vi bør kjenne «grensene» for SQL så vi ikke kaster bort mye tid med å løse en umulig oppgave. Kan være bedre å kombinere SQL med «generelle» programmeringsspråk. Databaser Leksjon 4: Avansert bruk av SQL - 15