Yhdiste, leikkaus, erotus ym. SQL tarjoaa myös relaatioalgebran operaatiot yhdiste, leikkaus, erotus Näissä operaatioissa taulujen on oltava samarakenteisia, ts. niissä on oltava samantyyppiset vastinsarakkeet. Informaatiojärjestelmät, kevät 1997 4.2.1999 1 Esimerkki. pankkien talletus- ja lainatietokanta: ASIAKAS AsOsoite AsKaupunki Ukkonen Kaivotie Vantaa Koivikko Helsinki Länsitie Vantaa Itäväylä Helsinki Laine Otakaari Espoo TALLETUS KNimi Tilinro Summa KOP2 22222 2000 SYP5 55555 Ukkonen 5000 KOP2 33333 3000 KONTTORI KNimi Varat KKaupunki SYP5 210 000 Espoo KOP2 170 000 Tampere PSP6 80 000 Espoo LAINA KNimi Tilinro Summa SYP5 500 Laine 4000 KOP2 202 2500 PSP6 660 Ukkonen 500 KOP2 444 1500 Informaatiojärjestelmät, kevät 1997 4.2.1999 2 Tietojenkäsittelytieteen laitos 1/15
Yhdiste (Union) (kysely) UNION (kysely) Luettele ne asiakkaat, joilla on talletus tai laina tai molemmat KOP2-konttorissa. (SELECT WHERE KNimi = 'KOP2') UNION (SELECT FROM Laina WHERE KNimi = 'KOP2'); Informaatiojärjestelmät, kevät 1997 4.2.1999 3 Leikkaus (intersect) (kysely) INTERSECT (kysely) Luettele ne asiakkaat, joilla on sekä talletus että laina KOP2-konttorissa. (SELECT DISTINCT WHERE KNimi = 'KOP2') INTERSECT (SELECT DISTINCT FROM Laina WHERE KNimi = 'KOP2'); Informaatiojärjestelmät, kevät 1997 4.2.1999 4 Tietojenkäsittelytieteen laitos 2/15
Leikkaus Miksi SELECT DISTINCT? INTERSECT ei poista duplikaatteja (niitä ei leikkausoperaation tuloksena synny). Informaatiojärjestelmät, kevät 1997 4.2.1999 5 Erotus (except/minus) (kysely) EXCEPT (kysely) Luettele ne asiakkaat, joilla on talletus mutta ei lainaa KOP2-konttorissa. (SELECT DISTINCT WHERE KNimi ='KOP2') EXCEPT (SELECT FROM Laina WHERE KNimi = 'KOP2'); Informaatiojärjestelmät, kevät 1997 4.2.1999 6 Tietojenkäsittelytieteen laitos 3/15
Erotus Miksi kyselyn jälkimmäisessä puoliskossa ei käytetä SELECT DISTINCT -muotoa? UNION, INTERSECT ja EXCEPT standardissa, MINUS Oraclessa Informaatiojärjestelmät, kevät 1997 4.2.1999 7 Esimerkkikanta. Kirjasto KIRJA ASIAKAS Hetu Nimi 111111-1111 Ukkonen 101010-1010 090909-9999 121212-2222 Sippu ISBN Kirjannimi Tekijä 111 Oh! Pascal Cooper 552 Algebra I Myrberg 444 Samlade dikter Fröding 898 Lisp Winston 789 Electronics Smith LAINAUS Hetu ISBN Pvm 101010-1010 111 12.02.94 121212-2222 898 22.05.94 101010-1010 789 24.03.94 111111-1111 444 01.01.94 Informaatiojärjestelmät, kevät 1997 4.2.1999 8 Tietojenkäsittelytieteen laitos 4/15
Sisäkkäiset kyselyt WHERE-lauseen ehdon osapuolena voi olla toinen kysely. Niiden lainaajien nimet, joilla on kirjoja lainassa? SELECT Nimi FROM Asiakas Asi, Lainaus Lai WHERE Asi.Hetu = Lai.Hetu; Informaatiojärjestelmät, kevät 1997 4.2.1999 9 Edellinen kysely sisäkkäisten kyselyiden avulla SELECT Nimi FROM Asiakas WHERE Hetu IN (SELECT Hetu FROM Lainaus); Sisempi kysely palauttaa joukon hetuja: Hetu 101010-1010 121212-2222 101010-1010 111111-1111 Informaatiojärjestelmät, kevät 1997 4.2.1999 10 Tietojenkäsittelytieteen laitos 5/15
Ulommassa kyselyssä ASIAKAStaulusta valitaan ne rivit, joiden hetut täsmäävät sisäkyselyn kanssa: SELECT Nimi FROM Asiakas WHERE Hetu IN sisäkyselyn hetut; Mitä kysely lopulta tulostaa? Nimi Ukkonen Sippu Informaatiojärjestelmät, kevät 1997 4.2.1999 11 Niiden kirjojen nimet, jotka on lainattu 01.03.94 jälkeen: SELECT Kirjannimi FROM Kirja K, Lainaus L WHERE (K.ISBN = L.ISBN) AND (L.Pvm > 01.03.94); Tai näin: SELECT Kirjannimi FROM Kirja WHERE ISBN IN (SELECT ISBN FROM Lainaus WHERE Pvm > 01.03.94); ISBN 898 789 Kirjannimi Lisp Electronics Informaatiojärjestelmät, kevät 1997 4.2.1999 12 Tietojenkäsittelytieteen laitos 6/15
Sisäkkäiset kyselyt ISBN:t oltava samaa tyyppiä, attribuuttien nimien ei toki tarvitse olla samat. IN-määre tutkii joukkoon kuulumista ( ). Yhtä monta IN- määrettä ( sisäkkäistä pykälää ) kuin on liitosehtojakin. Informaatiojärjestelmät, kevät 1997 4.2.1999 13 Sisäkkäiset kyselyt SELECT Kirjannimi FROM Kirja, Lainaus, Asiakas WHERE Kirja.ISBN=Lainaus.ISBN AND Lainaus.Hetu=Asiakas.Hetu AND Asiakas.Nimi= ; SELECT Kirjannimi FROM Kirja WHERE ISBN IN (SELECT ISBN FROM LAINAUS WHERE Hetu IN (SELECT Hetu FROM ASIAKAS ISBN WHERE Nimi= )); Hetu 101010-1010 Informaatiojärjestelmät, kevät 1997 4.2.1999 14 111 789 Kirjannimi Oh! Pascal Electronics Tietojenkäsittelytieteen laitos 7/15
Riippumaton sisäkysely SELECT Pvm FROM Lainaus WHERE Hetu IN Hetu (SELECT Hetu 101010-1010 FROM Asiakas WHERE Nimi = ''); Pvm 12.02.94 24.03.94 Informaatiojärjestelmät, kevät 1997 4.2.1999 15 Kytketty sisäkysely sisemmän kyselyn WHERE-osassa viittaus ulomman kyselyn relaatioon => sisempi kysely mahdoton toteuttaa erikseen "ykkösvaiheena" (vrt. edell. sivu) => toteutetaan sisäkysely kerran jokaista ulomman kyselyn mahdollista riviä kohti Informaatiojärjestelmät, kevät 1997 4.2.1999 16 Tietojenkäsittelytieteen laitos 8/15
Kytketty sisäkysely Kirjojen nimet, jotka ovat lainassa ja kirjan tekijän nimi on sama kuin lainaajan nimi: SELECT Kirjannimi FROM Kirja, Lainaus, Asiakas WHERE Lainaus.Hetu=Asiakas.Hetu AND Lainaus.ISBN=Kirja.ISBN AND Asiakas.Nimi = Kirja.Tekijä; Informaatiojärjestelmät, kevät 1997 4.2.1999 17 Kytketty sisäkysely SELECT Kirjannimi FROM Kirja WHERE ISBN in ( SELECT ISBN FROM Lainaus, Asiakas WHERE Lainaus.Hetu=Asiakas.Hetu and Nimi = Kirja.Tekijä ); Informaatiojärjestelmät, kevät 1997 4.2.1999 18 Tietojenkäsittelytieteen laitos 9/15
Esimerkki. pankkien talletus- ja lainatietokanta: ASIAKAS AsOsoite AsKaupunki Ukkonen Kaivotie Vantaa Koivikko Helsinki Länsitie Vantaa Itäväylä Helsinki Laine Otakaari Espoo TALLETUS KNimi Tilinro Summa KOP2 22222 2000 SYP5 55555 Ukkonen 5000 KOP2 33333 3000 KONTTORI KNimi Varat KKaupunki SYP5 210 000 Espoo KOP2 170 000 Tampere PSP6 80 000 Espoo LAINA KNimi Tilinro Summa SYP5 500 Laine 4000 KOP2 202 2500 PSP6 660 Ukkonen 500 KOP2 444 1500 Informaatiojärjestelmät, kevät 1997 4.2.1999 19 Leikkaus (INTERSECT) sisäkyselyn avulla Luettele ne asiakkaat, joilla on sekä talletus että laina KOP2-konttorissa. SELECT DISTINCT WHERE (KNimi = 'KOP2') AND IN (SELECT Asnimi FROM Laina WHERE Knimi = 'KOP2'); Informaatiojärjestelmät, kevät 1997 4.2.1999 20 Tietojenkäsittelytieteen laitos 10/15
IN-määrettä voi edeltää myös useampi attribuutti. Edellinen kysely toisin: SELECT DISTINCT WHERE (KNimi = 'KOP2') AND (KNimi, ) IN Laine (SELECT Knimi, Asnimi FROM Laina); KNimi SYP5 KOP2 PSP6 KOP2 Ukkonen Informaatiojärjestelmät, kevät 1997 4.2.1999 21 Erotus (MINUS) sisäkyselyn avulla Luettele ne asiakkaat, joilla on talletus mutta ei lainaa KOP2-konttorissa. SELECT DISTINCT WHERE (KNimi = 'KOP2') AND NOT IN (SELECT Asnimi FROM Laina WHERE Knimi = 'KOP2'); Informaatiojärjestelmät, kevät 1997 4.2.1999 22 Tietojenkäsittelytieteen laitos 11/15
Tai taas toisin: SELECT DISTINCT WHERE (KNimi = 'KOP2') AND (KNimi, ) NOT IN KNimi (SELECT Knimi, Asnimi SYP5 Laine FROM Laina); KOP2 PSP6 KOP2 Ukkonen Informaatiojärjestelmät, kevät 1997 4.2.1999 23 Lisäpiirteitä: Samaan tauluun viittaaminen aliaksilla Luettele ne asiakkaat, joilla on talletus sellaisessa konttorissa, jossa lla on talletus. SELECT DISTINCT Tal. T, Talletus Tal WHERE (T.Asnimi = '') AND (T.KNimi = Tal.KNimi); Informaatiojärjestelmät, kevät 1997 4.2.1999 24 Tietojenkäsittelytieteen laitos 12/15
Lisäpiirteitä: Samaan tauluun viittaaminen viitenimillä T KNimi Tilinro Summa KOP2 22222 2000 SYP5 55555 Ukkonen 5000 KOP2 33333 3000 TAL KNimi Tilinro Summa KOP2 22222 2000 SYP5 55555 Ukkonen 5000 KOP2 33333 3000 Informaatiojärjestelmät, kevät 1997 4.2.1999 25 Toinen tapa on sisäkyselyn ja IN-määreen käyttäminen: SELECT DISTINCT WHERE KNimi IN Knimi (SELECT Knimi KOP2 WHERE = ''); Miksi DISTINCT-määre? Informaatiojärjestelmät, kevät 1997 4.2.1999 26 Tietojenkäsittelytieteen laitos 13/15
Lisäpiirteitä: SOME ja ALL IN-määreellä testataan, kuuluuko WHEREosan alkio sisäkyselyn tuottamaan joukkoon vai ei, eli vertailun osapuolen on oltava sama kuin jokin joukon alkio (siis =) Joskus voidaan tarvita myös vertailuoperaattoreita: < <= > >= <> Informaatiojärjestelmät, kevät 1997 4.2.1999 27 SOME Luettele ne konttorit, joilla on enemmän varoja kuin jollakin Espoossa sijaitsevalla konttorilla. (Eli ne, joilla on enemmän kuin sillä Espoossa olevalla konttorilla, jolla on kaikkein vähiten!) SELECT KNimi KNimi FROM Konttori SYP5 Varat WHERE Varat > SOME 210 000 80 000 SOME:n tilalle käy ANY! (SELECT Varat FROM Konttori WHERE KKaupunki = 'Espoo'); KOP2 Informaatiojärjestelmät, kevät 1997 4.2.1999 28 Tietojenkäsittelytieteen laitos 14/15
ALL Luettele ne konttorit, joilla on enemmän varoja kuin millä tahansa Espoossa sijaitsevalla konttorilla. SELECT KNimi KNimi FROM Konttori WHERE Varat > ALL tyhjä! (SELECT Varat FROM Konttori WHERE KKaupunki = 'Espoo'); Varat 210 000 80 000 Informaatiojärjestelmät, kevät 1997 4.2.1999 29 Vertailuoperaattorien käyttö Vertailuoperaattoreita voidaan käyttää suoraan (ilman SOMEa tai ALLia), jos ollaan varmoja siitä, että sisäkysely tuottaa tulokseksi aina täsmälleen yhden rivin. Esimerkiksi koostefunktioiden yhteydessä käy näin. Informaatiojärjestelmät, kevät 1997 4.2.1999 30 Tietojenkäsittelytieteen laitos 15/15