ALIKYSELYT (IN, EXISTS)

Alikyselyillä voidaan rajata varsinaista kyselyä käyttämällä toista pääkyselyn sisään kirjoitettua SELECT-lausetta. Sisäkkäisiä alikyselyjä voi olla monta tasoa. Alikyselyn suoritus alkaa alimmalta tasolta ja se suoritetaan aina yhden kerran koko kyselyä kohti. Poikkeuksena ovat sellaiset alikyselyt, joissa sidotaan jokin ylemmän kyselyn kenttä alempaan kyselyyn. Tällöin alikysely on pakko suorittaa uudelleen jokaista ylemmän kyselyn riviä kohti. Esimerkkejä tällaisista kyselyistä on EXISTS-lauseen kohdalla myöhemmin tässä luvussa. Alikyselyistä voi tulla tuloksena joko vain täsmälleen yksi rivi tai sitten useampia rivejä. Yhden rivin tuloksenaan tuottavien alikyselyjen yhteydessä voidaan käyttää aivan tavallisia vertailuoperaattoreita.

/* Haetaan kaikki ne tenttisuoritukset, joiden tulos on sama kuin korkein tenttisuoritus. */

SELECT *

FROM Tentit

WHERE arvosana = (SELECT Max(arvosana) FROM Tentit)

Sotu

Kurssitunnus

Pvm

Arvosana

010177-333A

TIE001

1.1.1995

3

300375-1234

TIE140

12.3.1998

3

Saataessa useampirivinen tulos tarvitaan uusia operaattoreita. Alikysely palauttaa joukon, josta IN-operaattorilla voidaan testata löytyykö vastaava arvo joukosta. IN-operaattori kelpaa vain, jos vaaditaan tarkkaa yhtäsuuruutta.

/* Haetaan niiden sotut jotka eivät ole tehneet yhtään tenttiä vrt. EXCEPT-lause */

SELECT sotu

FROM Oppilaat

WHERE SOTU NOT IN (

SELECT sotu

FROM Tentit

)

sotu

110573-111Y

100132-9876

/* haetaan niiden sotut, jotka ovat käyneet tentissä vrt. INTERSECT-lause */

SELECT sotu

FROM Oppilaat

WHERE SOTU IN (

SELECT sotu

FROM Tentit

)

sotu

121273-000X

010177-333A

300375-1234

100135-0000

111170-7070

ANY, SOME tai ALL -operaattoreita käytetään jos vertailuehtona on <, >, <= tai >=.

  1. AN

Y palauttaa tosi, jos alikyselyn mikä tahansa arvo täyttää ehdon.

  1. SOM

E toimii samoin kuin ANY.

  1. AL

L palauttaa tosi, jos alikyselyn jokainen yksittäinen arvo täyttää ehdon.

/* Haetaan kaikki ne tenttisuoritukset, jotka ovat huonompia kuin mikään suoritus kurssilta TIE160. */

SELECT *

FROM Tentit

WHERE arvosana < ALL (

SELECT arvosana

FROM Tentit

WHERE kurssitunnus = 'TIE160'

)

Sotu

Kurssitunnus

Pvm

Arvosana

121273-000X

TIE001

1.1.1995

0

010177-333A

TIE110

14.5.1998

0

300375-1234

TIE110

1.8.2000

0

/* Haetaan kaikki ne tenttisuoritukset, jotka ovat huonompia kuin jokin suoritus kurssilta TIE160 */

SELECT *

FROM Tentit

WHERE arvosana < ANY (

SELECT arvosana

FROM Tentit

WHERE kurssitunnus = 'TIE160'

)

Sotu

Kurssitunnus

Pvm

Arvosana

121273-000X

TIE001

1.1.1995

0

010177-333A

TIE110

12.3.1998

1,75

010177-333A

TIE160

12.5.1999

1

010177-333A

TIE110

14.5.1998

0

010177-333A

TIE110

19.9.1998

1

111170-7070

TIE150

1.1.1995

1

300375-1234

TIE110

1.8.2000

0

Kaikki ANY-, SOME- ja ALL-kyselyt voidaan muuttaa käyttämään EXISTS-komentoa. EXISTS ei palauta mitään arvojoukkoa vaan vain tiedon siitä oliko alikyselyn tulos tosi vai epätosi. Suositellaankin, että käytettäisiin ennemmin EXISTS-komentoa kuin ANY-, SOME- tai ALL-operaattoreita, koska EXISTS vaatii vähemmän resursseja toimiakseen.

/* Haetaan niiden sotut, jotka eivät ole tehneet yhtään tenttiä. */

SELECT sotu

FROM Oppilaat O

WHERE NOT EXISTS (

SELECT *

FROM Tentit

WHERE sotu = O.sotu

)

sotu

110573-111Y

100132-9876

/* Haetaan niiden sotut, jotka ovat käyneet tentissä. */

SELECT sotu

FROM Oppilaat O

WHERE EXISTS (

SELECT *

FROM Tentit

WHERE sotu = O.sotu

)

sotu

010177-333A

100135-0000

111170-7070

121273-000X

300375-1234