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 >=.
Y palauttaa tosi, jos alikyselyn mikä tahansa arvo täyttää ehdon.
E toimii samoin kuin ANY.
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 |