Sisäkkäiset ja linkitetyt alikyselyt SQL:ssä, EXISTS-predikaatti. EXISTS-operaattorin käyttäminen Kyselyt olemassa-funktiolla

MISSÄ OLEMASSA

Alikyselystä tarkistetaan yksi tai useampi rivi. Jos vähintään yksi rivi täyttää kyselyn, looginen arvo TOSI palautetaan. Kun valinnainen NOT-avainsana on määritetty, looginen arvo TOSI palautetaan, jos alikysely ei palauta vastaavia rivejä.

alikysely

Täysin muodostetun alikyselyn perusteella haetaan tuloksena oleva tietojoukko.

Yleiset säännöt

EXISTS-operaattori tarkistaa, onko pääkyselyn alikyselyssä yksi tai useampi rivi.

SELECT * FROM työt WHERE NOT EXISTS (SELECT * FROM työntekijä WHERE jobs.job_id=employye. job_id);

Tämä esimerkki vahvistaa tietueiden alikyselyssä valinnaisen NOT-avainsanan avulla. Seuraava esimerkki hakee tiettyjä tietueita alikyselystä päätulosjoukon hakemiseksi.

SELECT au_lname FROM authors WHERE EXISTS (SELECT * FROM julkaisijat WHERE authors.city=publishers.city);

Tämä kysely palauttaa kustantajien kanssa samassa kaupungissa asuvien tekijöiden sukunimet (au_lname). Huomaa, että voit käyttää alikyselyssä tähteä, koska alikyselyn pitäisi palauttaa vain yksi tietue, jonka looginen arvo on TOSI. Tällaisissa tapauksissa sarakkeilla ei ole merkitystä. Keskeinen asia on merkkijonon olemassaolo.

Monissa kyselyissä EXISTS-operaattori suorittaa saman toiminnon kuin ANY. EXISTS-operaattori on yleensä tehokkain, kun sitä käytetään korreloitujen kyselyiden kanssa.

EXISTS-operaattori vastaa semanttisesti ANY-operaattoria.

EXISTS-lauseen alikysely suorittaa tyypillisesti toisen kahdesta hausta. Ensimmäinen vaihtoehto on käyttää tähti-jokerimerkkiä (esim. SELECT * FROM…), jolloin et hae mitään tiettyä saraketta tai arvoa. Tähti tarkoittaa tässä "mitä tahansa saraketta". Toinen vaihtoehto on valita vain yksi tietty sarake alikyselyssä (esimerkiksi SELECT aujd FROM). Jotkut yksittäiset alustat sallivat alikyselyt useissa sarakkeissa (esim. SELECT aujd, aujname FROM...). Tämä ominaisuus on kuitenkin harvinainen, ja sitä tulisi välttää koodissa, joka on siirrettävä muille alustoille.

Erot alustojen välillä

Kaikki alustat tukevat EXISTS-operaattoria yllä kuvatussa muodossa.

"Aiemmin se oli helpompaa" - ajattelin istuutuessani optimoimaan seuraavaa SQL-kyselyä johtamisstudio. Kun kirjoitin MySQL:llä, kaikki oli todella yksinkertaisempaa - joko toimii tai ei. Tai hidastaa tai ei. Selitys ratkaisi kaikki ongelmani, muuta ei tarvittu. Nyt minulla on tehokas kehitysympäristö, virheenkorjaus ja pyyntöjen ja proseduurien/toimintojen optimointi, ja kaikki tämä kasa luo mielestäni vain lisää ongelmia. Ja kaikki miksi? Koska sisäänrakennettu kyselyn optimoija on paha. Jos kirjoitan MySQL:ssä ja PostgreSQL:ssä

Valitse * a, b, c, jossa a.id = b.id, b.id = c.id

ja jokaisessa levyssä on vähintään 5k viivaa - kaikki roikkuu. Ja luojan kiitos! Koska muuten kehittäjässä parhaimmillaan laiskuus kehittyy kirjoittamaan oikein, ja pahimmillaan hän ei ymmärrä ollenkaan mitä tekee! Loppujen lopuksi sama kysely MSSQL:ssä kulkee samalla tavalla

Valitse * liitoksesta b a.id = b.id liitos c kohdassa b.id = c.id

Sisäänrakennettu optimoija kampaa bydlozapros ja kaikki on kunnossa.

Hän myös päättää itse, mitä on parempi tehdä - olemassa vai liittyä ja paljon muuta. Ja kaikki toimii mahdollisimman optimaalisesti.

On vain yksi MUTTA. Jossain vaiheessa optimoija kompastuu monimutkainen kysely ja kippaa, ja sitten saat valtavan ongelman. Ja saat sen, ehkä et heti, mutta kun pöytien paino saavuttaa kriittisen massan.

Tämä on siis artikkelin pointti. on olemassa ja on erittäin raskasta toimintaa. Itse asiassa tämä on erillinen alikysely jokaiselle tulosrivit. Ja jos myös pesimä on läsnä, tämä on yleensä ruhovalo. Kaikki on ok, kun 1, 10, 50 riviä palautetaan. Et tunne eroa, ja ehkä liittyminen on vielä hitaampaa. Mutta kun 500 vedetään pois, ongelmat alkavat. 500 alipyyntöä yhdessä pyynnössä on vakava asia.

Päästäminen ja olemassaolo ovat ihmisen ymmärryksen kannalta parempia, mutta yli 50 riviä palauttavien kyselyjen aikakustannusten kannalta ne eivät ole hyväksyttäviä.

On tarpeen tehdä varaus, että luonnollisesti, jos se laskee jossain, sen täytyy saapua jonnekin. Kyllä, liittäminen on muistin kannalta resurssivaltaisempaa, koska koko arvotaulukon ja sen samanaikainen pitäminen ja sen käyttäminen on kalliimpaa kuin alikyselyjen vetäminen jokaiselle riville, mikä vapauttaa nopeasti muistia. Sinun on tarkasteltava erityisesti pyyntöä ja mitattava, onko kriittistä käyttää ylimääräistä muistia ajan vuoksi vai ei.

Annan esimerkkejä täydellisistä analogioista. Yleisesti ottaen en ole vielä nähnyt niin monimutkaisia ​​pyyntöjä, joita ei voitaisi purkaa liitoskaskadiksi. Anna sen kestää päivän, mutta kaikki voidaan paljastaa.

Valitse * a:sta jossa a.id in (valitse id kohdasta b) valitse * kohdasta a, jossa on (valitse alkuun 1 1 kohdasta b, jossa b.id = a.id) valitse * liitoksesta b kohdassa a.id = b. id valitse * kohdasta a, jossa a.id ei ole (valitse id kohdasta b) valitse * a:sta jossa ei ole (valitse alkuun 1 1 kohdasta b, jossa b.id = a.id) valitse * vasemmasta liitoksesta b kohdassa a. id = b.id jossa b.id on tyhjä

Toistan - MSSQL optimoija optimoi nämä esimerkit maksimi suorituskyky ja sellaisissa yksinkertaisissa pyynnöissä ei ole koskaan tyhmyyttä.

Tarkastellaan nyt esimerkkiä todellisesta kyselystä, joka piti kirjoittaa uudelleen, koska joissain valinnoissa se vain roikkui tiukasti (rakenne on hyvin yksinkertaistettu ja käsitteet on korvattu, ei tarvitse pelätä joitain ei- optimaalinen tietokantarakenne).

Sinun on poistettava kaikki päällekkäiset "tuotteet" eri tileiltä keskittyen tuotteen, sen ryhmän ja mahdollisen yläryhmän parametreihin.

Valitse d.PRODUCT_ID tuotteista PRODUCT s, PRODUCT_GROUP sg vasemmalle liity M_PG_DEPENDENCY sd on (sg.PRODUCT_GROUP_ID = sd.M_PG_DEPENDENCY_CHILD_ID), PRODUCT d, PRODUCT_GROUP dg vasemmalle = PRODUCT_GROUPs =PRODUCT_GROUPs.DEYSDM_PG_DEPENDENCY dd.ENGIDsM_PG_DEPENDENCY dd. .PRODUCT_GROUP_ID ja d.PRODUCT_GROUP_ID=dg.PRODUCT_GROUP_ID ja sg.PRODUCT_GROUP_PERSPEC=dg.PRODUCT_GROUP_PERSPEC ja sg.PRODUCT_GROUP_NAME=dg.PRODUCT_GROUP_NAME ja s.PRODUCT_NAME=d.PRODUCT_NAME ja s.PRODUCT_TYPE=d.CUCU_PRODUCT_TYPE ja.REISSE. ja s.PRODUCT_MULTISELECT=d.PRODUCT_MULTISELECT ja dg.PRODUCT_GROUP_IS_TMPL=0 and ((sd.M_PG_DEPENDENCY_CHILD_ID on tyhjä ja dd.M_PG_DEPENDENCY_CHILD_ID on tyhjä) tai on olemassa (valitse 1 tuotteista PRODUCT_GROUP1, missä PRODUCT_GROUP_gEN_GROUP1, DEPG_GROUP1, DEPGIDd1 .M_PG_DEPENDENCY_PARENT_ID = dg1.PRODUCT_GROUP_ID ja sg1.PRODUCT_GROUP_PERSPEC=dg1.PRODUCT_GROUP_PERSPEC ja sg1.PRODUCT_GROUP_NAME=dg1.PRODUCT_GROUP_N AME ja))

Ja niin on siinä tapauksessa, kun optimoija taittui. Ja jokaiselle riville teloitettiin raskas olemassaolo, joka tappoi tukikohdan.

Valitse d.PRODUCT_ID tuotteesta PRODUCT s liittyä PRODUCT_GROUP sg on PRODUCT_TYPE=d.PRODUCT_TYPE ja s.PRODUCT_NAME=d.PRODUCT_NAME ja s.PRODUCT_IS_SECURE=d.PRODUCT_IS_SECURE ja s.PRODUCT_MULTISELECT=d.PRODUCT_MULTISELECT liittyä PRODUCT_GROUP-sg on .PRODUCT_GROUP_ID join PRODUCT_GROUP dg on d.PRODUCT_GROUP_ID=dg.PRODUCT_GROUP_ID and sg.PRODUCT_GROUP_NAME=dg.PRODUCT_GROUP_NAME and sg.PRODUCT_GROUP_PERSPEC=dg.PRODUCT_GROUP_PERSPEC left join M_PG_DEPENDENCY sd on sg.PRODUCT_GROUP_ID = sd.M_PG_DEPENDENCY_CHILD_ID left join M_PG_DEPENDENCY dd on dg.PRODUCT_GROUP_ID = dd.M_PG_DEPENDENCY_CHILD_ID left join PRODUCT_GROUP sgp on sgp.PRODUCT_GROUP_ID = sd.M_PG_DEPENDENCY_PARENT_ID left join PRODUCT_GROUP dgp on dgp.PRODUCT_GROUP_ID = dd.M_PG_DEPENDENCY_PARENT_ID and sgp.PRODUCT_GROUP_NAME = dgp.PRODUCT_GROUP_NAME and isnull(sgp.PRODUCT_GROUP_IS_TMPL, 0) = isnull(dgp. PRODUCT_GROUP_IS_TMPL , 0) jossa (sd.M_PG_DEPENDENCY_CHILD_ID on tyhjä ja dd.M_PG_DEPENDENCY_CHILD_ID on tyhjä) tai (sgp.PRODUCT_GROUP_NAME ei ole tyhjä ja dgp.PRODUCT_GROUP_NAME ei ole tyhjä) mene

Näiden muutosten jälkeen näkymän suorituskyky kasvoi eksponentiaalisesti löydettyjen tuotteiden määrässä. Tarkemmin sanottuna hakuaika pysyi käytännössä riippumattomana osumien määrästä ja oli aina hyvin pieni. Kuten sen pitääkin olla.

Tämä on selkeä esimerkki siitä, kuinka luottavainen MSSQL-optimoija voi leikkiä julmaa vitsiä. Älä luota häneen, älä ole laiska, liity kahvoihin, mieti joka kerta kumpi on parempi tässä tilanteessa - olemassa, mukaan vai liittyä.

SQL EXISTS -predikaatti suorittaa loogisen tehtävän. SISÄÄN SQL-kyselyt tätä predikaattia käytetään ilmaisuissa, kuten

OLEMASSA (VALITSE * TABLE_NAME...).

Tämä lauseke palauttaa tosi, kun kysely löytää yhden tai useamman ehtoa vastaavan rivin, ja epätosi, kun rivejä ei löydy.

EI OLE OLEMASSA, päinvastoin. Ilmaisu

EI OLE OLEMASSA (VALITSE * TABLE_NAME...)

palauttaa tosi, kun kyselylle ei löydy rivejä, ja epätosi, kun vähintään yksi rivi löytyy.

Yksinkertaisimmat kyselyt SQL EXISTS -predikaatilla

Esimerkeissä työskentelemme kirjastotietokannan ja sen taulukoiden "Kirja käytössä" (BOOKINUSE) ja "Käyttäjä" (USER) kanssa. Toistaiseksi tarvitsemme vain "Kirja käytössä" -taulukon (BOOKINUSE).

TekijäOtsikkoPub vuosiInv_NoKäyttäjätunnus
TolstoiSota ja rauha2005 28 65
TšehovKirsikkatarha2000 17 31
TšehovValitut tarinat2011 19 120
TšehovKirsikkatarha1991 5 65
Ilf ja PetrovKaksitoista tuolia1985 3 31
Majakovskirunoja1983 2 120
PalsternakkaTohtori Zhivago2006 69 120
Tolstoisunnuntai2006 77 47
TolstoiAnna Karenina1989 7 205
PushkinKapteenin tytär2004 25 47
GogolPelaa2007 81 47
TšehovValitut tarinat1987 4 205
PalsternakkaSuosikit2000 137 18

Esimerkki 1 Selvitä niiden käyttäjien tunnukset, joille Tolstoi on myöntänyt kirjoja ja joille on myös Tšehovin kirjoja. Ulompi kysely valitsee tiedot käyttäjistä, joille on myönnetty Tolstoin kirjoja, ja EXISTS-predikaatti määrittää lisäehdon, joka tarkistetaan sisäisessä kyselyssä - käyttäjät, joille on myönnetty Tšehovin kirjoja. Lisäehto sisäisessä kyselyssä on ulkoisen ja sisäisen kyselyn käyttäjätunnusten vastaavuus: User_ID=tols_user.user_id. Pyyntö tulee olemaan seuraava:

Tämä kysely palauttaa seuraavan tuloksen:

Erot EXISTS- ja IN-predikaattien välillä

Ensi silmäyksellä kyselyissä, joissa on predikaatti EXISTS, saatat saada vaikutelman, että se on identtinen predikaatti IN. Tämä on väärin. Vaikka ne ovat hyvin samanlaisia. IN-predikaatti etsii arvoja argumentissa määritellyltä alueelta, ja jos sellaisia ​​on, kaikki tätä aluetta vastaavat rivit valitaan. EXISTS-predikaatin toiminnan tulos on kyllä ​​tai ei vastaus kysymykseen, onko ylipäätään arvoja, jotka vastaavat argumentissa määriteltyjä. Lisäksi IN-predikaattia edeltää sen sarakkeen nimi, jolla etsitään riviä, jotka vastaavat alueen arvoja. Katsotaanpa esimerkkiä, joka näyttää eron EXISTS-predikaatin ja IN-predikaatin välillä, ja ongelman, joka on ratkaistu IN-predikaatilla.

Esimerkki 4 Hanki niiden käyttäjien tunnukset, jotka ovat myöntäneet kirjat kirjailijoille, joiden kirjat on kuitattu ulos käyttäjätunnuksella 31. Kysely on seuraava:

Käyttäjätunnus
120
65
205

Sisäinen kysely (IN:n jälkeen) valitsee kirjoittajat: Chekhov; Ilf ja Petrov. Ulompi kysely valitsee kaikki käyttäjät, joille nämä kirjailijat ovat saaneet kirjoja. Näemme, että toisin kuin EXISTS-predikaatti, IN-predikaattia edeltää sarakkeen nimi, tässä tapauksessa Author.

Kyselyt, joissa on EXISTS-predikaatti ja lisäehdot

Jos kyselyssä EXISTS-predikaatin lisäksi sovelletaan vähintään yhtä lisäehtoa, esim. aggregaattifunktiot, niin tällaiset kyselyt voivat palvella yksinkertaista data-analyysiä. Osoitetaan tämä seuraavalla esimerkillä.

Esimerkki 5 Määritä niiden käyttäjien tunnukset, joille on myönnetty vähintään yksi Pasternak-kirja ja joille on myönnetty enemmän kuin kaksi kirjaa. Kirjoitamme seuraavan kyselyn, jossa ensimmäisen ehdon määrittää EXISTS-predikaatti alikyselyllä ja toisen ehdon HAVING-operaattorilla on aina seurattava alikyselyä:

Kyselyn suoritustulos:

Käyttäjätunnus
120

Kuten BOOKINUSE-taulukosta näkyy, Pasternakin kirja myönnettiin myös käyttäjälle tunnuksella 18, mutta hänelle myönnettiin vain yksi kirja, eikä hän ole mukana valinnassa. Jos käytät COUNT-toimintoa uudelleen tällaiseen kyselyyn, mutta lasket valitut rivit (harjoittele tätä itse), saat tietoa siitä, kuinka moni Pasternakin kirjoja lukeva käyttäjä lukee myös muiden kirjoittajien kirjoja. Tämä on jo tietoanalyysin alalla.

Kyselyt EXISTS-predikaatilla kahdessa taulukossa

EXISTS-predikaattia käyttävät kyselyt voivat hakea tietoja useammasta kuin yhdestä taulukosta. Monet ongelmat voidaan ratkaista samalla tuloksella käyttämällä JOIN-ilmoitus, mutta joissain tapauksissa EXISTS-komennolla voit tehdä vähemmän vaivalloisen kyselyn. On suositeltavaa käyttää EXISTS-toimintoa tapauksissa, joissa tuloksena oleva taulukko sisältää sarakkeita vain yhdestä taulukosta.

Seuraavassa esimerkissä tarvitset samasta tietokannasta BOOKINUSE-taulukon lisäksi myös USER-taulukon.

Kyselyn tulos on seuraava taulukko:

Tekijä
Tšehov
Majakovski
Palsternakka

Kuten JOIN-käskyssä, tapauksissa, joissa on useampi kuin yksi taulukko, taulukon aliaksia tulisi käyttää tarkistamaan, että taulukoita yhdistävien avainten arvot täsmäävät. Esimerkissämme taulukon aliakset ovat bk ja us, ja taulukoita yhdistävä avain on User_ID.

EXISTS predikaatti useamman kuin kahden taulukon liitoksissa

Nyt näemme yksityiskohtaisemmin, miksi on parempi käyttää EXISTS tapauksissa, joissa vain yhden taulukon sarakkeet pääsevät tuloksena olevaan taulukkoon.

Työskentelemme "Real Estate" -tietokannan kanssa. Deal-taulukko sisältää tiedot kaupoista. Tämän taulukon tehtävillemme Tyyppi-sarake on tärkeä tapahtumatyyppiä koskevien tietojen kanssa - myynti tai vuokraus. Objektitaulukko sisältää tietoja objekteista. Tässä taulukossa tarvitsemme sarakkeiden Huoneet (huoneiden lukumäärä) ja LogBalc arvot, jotka sisältävät tietoja loggian tai parvekkeen olemassaolosta boolean-muodossa: 1 (kyllä) tai 0 (ei). Asiakas-, johtaja- ja omistajataulukot sisältävät tietoja asiakkaista, yritysjohtajista ja kiinteistöjen omistajista. Näissä taulukoissa FName ja LNimi ovat etu- ja sukunimet, vastaavasti.

Esimerkki 7 Tunnista asiakkaat, jotka ovat ostaneet tai vuokranneet kiinteistöjä, joissa ei ole loggiaa tai parveketta. Kirjoitamme seuraavan kyselyn, jossa EXISTS-predikaatti määrittää pääsyn kahden taulukon yhdistämisen tulokseen:

Koska asiakastaulukosta valitaan sarakkeet "tähti"-operaattorilla, kaikki tämän taulukon sarakkeet näytetään, joissa on niin monta riveä kuin on asiakkaita, jotka vastaavat EXISTS-predikaatin määrittämää ehtoa. Meidän ei tarvitse näyttää sarakkeita taulukoista, jotka on liitetty alikyselyyn. Siksi koneen ajan säästämiseksi haetaan vain yksi sarake. Tätä varten sanan SELECT jälkeen kirjoitetaan yksikkö. Samaa tekniikkaa käytetään seuraavien esimerkkien kyselyissä.

Kirjoita itse SQL-kysely EXISTS-predikaatilla ja katso sitten ratkaisu

Jatkamme SQL-kyselyjen kirjoittamista yhdessä EXISTS-predikaatin kanssa

Esimerkki 9 Selvitä vuokrattujen kohteiden omistajat. Kirjoitamme seuraavan kyselyn, jossa EXISTS-predikaatti määrittää myös pääsyn kahden taulukon yhdistämisen tulokseen:

Kuten edellisessä esimerkissä, kaikki kentät näytetään taulukosta, johon ulkoinen kysely on osoitettu.

Esimerkki 10 Määritä omistajien lukumäärä, joiden esineisiin johtaja Saveljev käytti. Kirjoitamme kyselyn, jossa ulompi kysely käyttää kolmen taulukon liitosta ja EXISTS-predikaatti määrittää pääsyn vain yhteen taulukkoon:

Kaikki kyselyt tarkistetaan olemassa olevan tietokannan perusteella. Onnistunut käyttö!

Relaatiotietokannat ja SQL-kieli

Novosibirskin valtion talous- ja hallintoakatemia

ASIAN LABORATORIO TYÖPAJA

"TIETOKANTA"

Laboratoriotyöt N 7

"SQL-tietokannan kieli: tietojen käsittelykomennot»

NOVOSIBIRSK 2000

SQL on Structured Query Language -kielen lyhyt nimi. Kielen nimestä käy selvästi ilmi, että sen päätarkoitus on tuottaa tietopyyntöjä tietokannasta. Tietojen valintakomennot muodostavat perustan tiedonkäsittelykielelle DML, joka on olennainen osa SQL-kieltä. DML koostuu kuitenkin enemmän kuin pelkistä komennoista tietojen hakemiseksi tietokannasta. Siellä on myös komentoja tietojen muokkaamiseen, tietojen hallintaan ja muihin.

Tämä laboratorio kattaa DML-kielen perusteet. Käynnissä laboratoriotyöt noudatamme SQL2-standardia.

Koska SQL on suuri kieli, otamme huomioon vain pääkomennot. Useita erityisiä SQL-ominaisuuksia käsitellään myöhemmissä laboratorioissa.

Laboratoriotöitä varten sinun tulee tuntea relaatiotietomallin perusteet, relaatioalgebran ja relaatiolaskennan perusteet sekä MS SQL Server DBMS:n kanssa työskentelyn periaatteet.

Laboratoriotyön tuloksena opit käsittelemään dataa SQL-komennoilla, huomioimaan MS SQL Server DBMS:ssä toteutetun kielen murteen.

JOHDANTO

SQL sisältää laajan valikoiman tiedonkäsittelyominaisuuksia sekä kyselyjen luomiseen että tietokannan päivittämiseen. Nämä ominaisuudet perustuvat vain tietokannan loogiseen rakenteeseen, eivät sen fyysiseen rakenteeseen, mikä on yhdenmukainen relaatiomallin vaatimusten kanssa.

Aluksi SQL:n syntaksirakenne perustui (tai ainakin näytti perustuvan) Coddin relaatiolaskentaan. Unioni oli ainoa tuettu relaatioalgebran operaatio.

SQL2:ssa edellisessä standardissa kehitetyn samanlaisen relaatiolaskennan syntaksin lisäksi operaatioiden yhdistäminen, leikkaus, ero ja liitos on toteutettu suoraan. Valinta-, projekti- ja tuotetoimintoja tuettiin (ja tuetaan edelleen) lähes suoraan, kun taas jako- ja toimeksiantotoimintaa tuetaan hankalammassa muodossa.

Kuvaamme ensin SQL-kyselykielen ja sitten sen tiedonsyöttö- ja muokkaustoiminnot. Tiedonmuutosoperaatiot kuvataan viimeisenä, koska niiden rakenne riippuu jossain määrin kyselykielen rakenteesta.

Yksinkertaiset kyselyt

Meille yksinkertainen pyyntö tulee kysely, joka käyttää vain yhtä tietokantataulukkoa. Yksinkertaiset kyselyt auttavat meitä havainnollistamaan SQL:n perusrakennetta.

Yksinkertainen pyyntö. Kysely, joka käyttää vain yhtä tietokantataulukkoa.

Pyyntö: Kuka työskentelee rappaajina?

WHERE SKILL_TYPE = "Kipteri"

Tulos:

G. Rickover

Tämä kysely kuvaa kolme yleisintä lauseita SQL: SELECT, FROM ja WHERE. Vaikka laitamme ne esimerkissämme eri riveille, ne voivat kaikki olla samalla rivillä. Ne voidaan myös sisentää eri tavalla, ja lauseiden sisällä olevat sanat voidaan erottaa mielivaltaisella määrällä välilyöntejä. Harkitse kunkin lauseen ominaisuuksia.

Valitse. SELECT-lause luettelee sarakkeet, jotka tulee sisällyttää tuloksena olevaan taulukkoon. Nämä ovat aina jonkin relaatiotaulukon sarakkeita. Esimerkissämme tuloksena oleva taulukko koostuu yhdestä sarakkeesta (NAME), mutta yleensä se voi sisältää useita sarakkeita; se voi sisältää myös laskettuja arvoja tai vakioita. Annamme esimerkkejä kustakin näistä vaihtoehdoista. Jos tuloksena oleva taulukko sisältää useamman kuin yhden sarakkeen, kaikki vaaditut sarakkeet luetellaan jälkeen SELECT komennot pilkun kautta. Esimerkiksi lause SELECT WORKER_ID, NAME johtaa taulukkoon, joka koostuu sarakkeista WORKER_ID ja NAME.

VALITSE lause. Määrittää tuloksena olevan taulukon sarakkeet.

From. FROM-lause määrittää yhden tai useamman taulukon, joita kysely käyttää. Kaikkien SELECT- ja WHERE-lauseiden sarakkeiden on oltava jossakin FROM-lauseessa luetelluista taulukoista. SQL2:ssa nämä taulukot voidaan määritellä skeemassa suoraan perustaulukoiksi tai tietonäkymiksi, tai ne voivat itse olla nimeämättömiä taulukoita, jotka johtuvat SQL-kyselyistä. Jälkimmäisessä tapauksessa kysely annetaan nimenomaisesti FROM-komennossa.

Lause FROM. Määrittää olemassa olevat taulukot, joihin kysely viittaa.

Missä. WHERE-lause sisältää ehdon. jonka perusteella taulukon rivit (taulukot) valitaan. Esimerkissämme ehtona on, että SKILL_TYPE-sarakkeen on sisällettävä vakio "Plaster" heittomerkkien sisällä, kuten aina tehdään tekstivakioiden kanssa SQL:ssä. WHERE-lause on haihtuvin SQL-komento; se voi sisältää monia erilaisia ​​ehtoja. Suuri osa esityksestämme on omistettu WHERE-lauseessa sallittujen erilaisten konstruktien havainnollistamiseen.

WHERE-lauseke. Määrittää ehdon, jonka perusteella rivit valitaan määritetyistä taulukoista.

Järjestelmä käsittelee yllä olevan SQL-kyselyn seuraavassa järjestyksessä: FROM, WHERE, SELECT. Toisin sanoen FROM-komennolla määritetyt taulukon rivit sijoitetaan työalueelle käsittelyä varten. WHERE-lausetta sovelletaan sitten jokaiselle riville peräkkäin. Kaikki rivit, jotka eivät täytä WHERE-lauseketta, jätetään huomioimatta. Sitten ne rivit, jotka täyttävät WHERE-lauseen, käsitellään SELECT-komennolla. Esimerkissämme NIMI valitaan jokaiselta tällaiselta riviltä, ​​ja kaikki valitut arvot näytetään kyselyn tuloksina.

Pyyntö: Anna kaikki tiedot toimistorakennuksista.

WHERE TYPE = "toimisto"

Tulos:

BLDG IDADDRESSTYPEQLTY LEVELSTATUS

312 Vyazov St., 123 Office 2 2

210 Berezovaya st. 1011 Office Z 1

111 Osinovaya st. 1213 Office 4 1

Tähti (*) SELECT-komennossa tarkoittaa "koko riviä". Tämä on kätevä lyhenne, jota käytämme usein.

Pyyntö: Mikä on kunkin sähköasentajan viikkopalkka?

VALITSE NIMI, "Viikkopalkka = ", 40 * HRLY_RATE

WHERE SKILL_TYPE = "Sähköasentaja"

Tulos:

M. Faraday Viikkopalkka = 500,00

H. Columbus Viikkopalkka = 620,00

Tämä kysely havainnollistaa sekä merkkivakioiden (esimerkissämme "Viikkopalkka = ") ja SELECT-komennon laskelmien käyttöä. SELECT-komennon sisällä voit suorittaa laskutoimituksia, joissa käytetään numeerisia sarakkeita ja numeerisia vakioita sekä tavallisia aritmeettisia operaattoreita ( +, -, *, /), ryhmitelty tarvittaessa suluissa. Olemme lisänneet myös uuden ORDER-komento BY, joka lajittelee kyselytuloksen nousevaan aakkosnumeeriseen järjestykseen määritetyn sarakkeen mukaan. Jos haluat lajitella tulokset laskevassa järjestyksessä, sinun on lisättävä komentoon DESC. ORDER BY -lause voi lajitella tulokset useiden sarakkeiden mukaan, joista jotkut nousevassa, toiset laskevassa järjestyksessä. Lajittelun ensisijaisen avaimen sarake määritetään ensin.

merkkivakio. Vakio, joka koostuu kirjaimista, numeroista ja "erikoismerkeistä".

Pyyntö: Kenen tuntipalkka on 10–12 dollaria?

WHERE HRLY_RATE >= 10 AND HRLY_RATE< - 12

Tulos:

TYÖNTEKIJÄN ID NAME HRLY_RATE SKILL_TYPE SUPV_ID

Tämä kysely kuvaa joitakin WHERE-komennon lisäominaisuuksia: vertailuoperaattorit ja Boolen AND-toiminto. Kuusi vertailuoperaattoria (=,<>(ei yhtä suuri),<, >, <=, >=). Boolen operaattoreita AND (AND), OR (OR) ja NOT (HE) voidaan käyttää yhdistelmäehtojen luomiseen tai ehdon kumoamiseen. Sulkeilla voidaan ryhmitellä ehtoja, kuten ohjelmointikielissä on yleistä.

Vertailuoperaattorit =,<>, <, >, <=, >=.

Boolen operaatiot JA (JA), TAI (OR) ja EI (HE) .

Voit myös käyttää BETWEEN (between) -operaattoria tämän kyselyn muotoiluun:

MISSÄ HRLY_RATE 10-12 VÄLILLÄ

BETWEEN:llä voidaan verrata jotakin arvoa kahteen muuhun arvoon, joista ensimmäinen on pienempi kuin toinen, jos vertailtava arvo voi olla yhtä suuri kuin kutakin annetuista arvoista tai mitä tahansa niiden välissä olevaa arvoa.

Kysely: Listaa rappaajat, kattotyöntekijät ja sähköasentajat.

WHERE SKILL_TYPE IN ("Rappaaja", "Katontekijä", "Sähköasentaja")

Tulos:

WORKER_ID NAME HRLY_RATE SKILL_TYPE SUPV_ID

1412 C. Nemo 13.75 Rappaaja 1520

2920 R. Garrett 10.00 Katontekijä 2920

1520 G. Rickover 11.75 Rappaaja 1520

Tämä kysely selittää IN (B) -vertailuoperaattorin käytön. WHERE-lause on totta, jos rivin ammattityyppi on suluissa olevan joukon sisällä, eli jos ammattityyppi on rappaja, kattomies tai sähköasentaja. Näemme jälleen IN-operaattorin alikyselyissä.

Oletetaan, että emme tarkalleen muista erikoisalan kirjoitusasua: "sähköasentaja" tai "elektroniikkainsinööri" tai jotain muuta. Jokerimerkit, jotka korvaavat määrittelemättömiä merkkijonoja, helpottavat virheellisten kirjoitusasujen löytämistä kyselystä.

Mallin symbolit. Merkit, jotka korvaavat määrittelemättömät merkkijonot.

Pyyntö: Listaa työntekijät, joiden tehtävätyyppi alkaa Elekillä.

WHERE SKILL_TYPE LIKE ("Elek%")

Tulos:

TYÖNTEKIJÄN TUNNUS NIMI HRLY_RATE SKILL_TYPE SUPV_ID

1235 M. Faraday 12.50 Sähköasentaja 1311

1311 H. Columbus 15.50 Sähköasentaja 1311

SQL:ssä on kaksi jokerimerkkiä: % (prosentti) ja _ (alaviiva). Alaviiva korvaa täsmälleen yhden määrittelemättömän merkin. Prosenttiosuus korvaa mielivaltaisen määrän merkkejä, alkaen nollasta. Kun käytetään jokerimerkkejä, LIKE-operaattoria (like) tarvitaan vertaamaan merkkimuuttujia vakioihin. Muita esimerkkejä:

NIMI LIKE "__Columbus"

NIMI LIKE "__K%"

Ensimmäisen esimerkin ehto on tosi, jos NIMI koostuu kahdesta merkistä, jota seuraa "Columbus". WORKER-taulukossa kaikki nimet alkavat ensimmäisellä alkukirjaimella ja pisteellä. Näin ollen tällä ehdolla me etsi kaikki työntekijät, joiden sukunimi on "Columbus". Toisen esimerkin ehdolla voit etsiä kaikki työntekijät, joiden sukunimet alkavat kirjaimella "K".

Pyyntö: Etsi kaikki työpaikat, jotka alkavat seuraavan kahden viikon aikana.

MISSÄ ALOITUS _DATE CURRENT_DATE JA

Tulos:(Oletetaan, että nykyinen päivämäärä on NYKYINEN PÄIVÄMÄÄRÄ = 10.10)

WORKER_ID BLDG_ID START_DATE NUM_DAYS

1235 312 10.10 5

1235 515 17.10 22

3231 111 10.10 8

1412 435 15.10 15

3231 312 24.10 20

1311 460 23.10 24

Tämä kysely havainnollistaa BETWEEN (beveen) -operaattorin käyttöä arvoilla, joiden tyyppi on päivämäärä (päivämäärä) ja intervalli (väli). CURRENT_DATE on funktio, joka palauttaa aina tämän päivän päivämäärän. Ilmaisu

CURRENT_DATE + INTERVAL "14" DAY

lisää kahden viikon ajanjakson nykyiseen päivämäärään. Siten ASSIGNMENT valitaan (olettaen, että tänään on 10/10), jos sen START_DATE sarakkeen arvo on välillä 10/10 ja 24/10. Tämä osoittaa, että voimme lisätä aikaväliarvoja päivämääräkenttiin. Lisäksi voimme kertoa aukkoarvot kokonaislukuarvoilla. Oletetaan esimerkiksi, että haluamme selvittää viikkojen lukumäärän tietyssä viikkomäärässä (merkitty muuttujalla NUM_WEEKS (NUMERO VIIKKOJA)). Voimme tehdä sen näin:

CURRENT_DATE + INTERVAL "7" DAY * NUM_WEEKS

2. Usean taulukon kyselyt

Kyky linkittää tietoelementtejä saman taulukon rajojen yli on tärkeää kaikilla tietokantakielillä. Relaatioalgebrassa tämä toiminto suoritetaan liitosoperaatiolla. Vaikka suuri osa SQL:stä perustuu suoraan relaatiolaskentaan, SQL linkittää tiedot eri taulukoista samalla tavalla kuin relaatioalgebran liitosoperaatio. Näytämme nyt, kuinka tämä tehdään. Harkitse kyselyä:

Pyyntö:

Vastaukseen tarvittavat tiedot ovat kahdessa taulukossa: TYÖNTEKIJÄ ja TEHTÄVÄ. SQL-ratkaisu edellyttää, että molemmat taulukot luetellaan FROM-lauseessa ja määritetään erityinen WHERE-lause:

VALITSE SKILL_TYPE

TYÖNTEKIJÄLTÄ, TEHTÄVÄ

WHERE TYÖNTEKIJÄN.TYÖNTEKIJÄN_TUNNUS = TEHTÄVÄ.TYÖNTEKIJÄN_TUNNUS

JA BLDG_ID = 435

Mitä täällä tapahtuu? Meidän on otettava huomioon kaksi vaihetta tietyn pyynnön käsittelyssä järjestelmässä.

1. Kuten tavallista, FROM-lause käsitellään ensin. Kuitenkin tässä tapauksessa, koska komennossa on määritetty kaksi taulukkoa, järjestelmä luo näiden taulukoiden riveistä suorakulmaisen tulon. Tämä tarkoittaa, että luodaan yksi (loogisesti) yksi iso taulukko, joka koostuu molempien taulukoiden sarakkeista ja jossa yhden taulukon jokainen rivi on paritettu toisen taulukon jokaisen rivin kanssa. Koska esimerkissämme WORKER-taulukossa on viisi saraketta ja ASSIGNMENT-taulukossa neljä saraketta, FROM-komennon luomassa karteesisessa tuotteessa on yhdeksän saraketta. Karteesisen tulon rivien kokonaismäärä on m * n, missä m on rivien lukumäärä WORKER-taulukossa; ja n on ASSIGNMENT-taulukon rivien lukumäärä. Koska TYÖNTEKIJÄ-taulukossa on 7 riviä ja ASSIGNMENT-taulukossa 19 riviä, karteesinen tuote sisältää 7x19 tai 133 riviä. Jos FROM-komennossa on lueteltu enemmän kuin kaksi taulukkoa, luodaan kaikkien komennossa määritettyjen taulukoiden karteesinen tulo.

karteesinen tuote. Yhden taulukon jokaisen rivin liittämisen tulos jokainen rivi toiseen taulukkoon.

2. Jättimäisen relaatiotaulukon luomisen jälkeen järjestelmä käyttää edelleen WHERE-lausetta kuten ennenkin. Jokainen FROM-komennolla luotu taulukon rivi. tarkistetaan WHERE-ehdon mukaan. Rivit, jotka eivät täytä ehtoa, jätetään huomioimatta. SELECT-lausetta sovelletaan sitten jäljellä oleviin riveihin.

WHERE-lause kyselyssämme sisältää kaksi ehtoa:

1. TYÖNTEKIJÄ. TYÖNTEKIJÄN_TUNNUS = TEHTÄVÄ.TYÖNTUNNUS

2.BLDG_ID = 435

Ensimmäinen näistä ehdoista on liitosehto. Huomaa, että koska sekä WORKER- että ASSIGNMENT-taulukot sisältävät sarakkeen nimeltä WORKER_ID, niiden karteesinen tulos sisältää kaksi samannimistä saraketta. Niiden erottamiseksi edeltää sarakkeen nimeä lähdetaulukon nimi ja erottele se pisteellä.

Ensimmäinen ehto tarkoittaa, että millä tahansa valitulla rivillä WORKER-taulukon WORKER_ID-sarakkeen arvon on vastattava TEHTÄVÄ-taulukon WORKER_ID-sarakkeen arvoa. Yhdistämme kaksi pöytää WORKER_ID:n kautta. Kaikki rivit, joissa näiden kahden sarakkeen arvot eivät ole samat, suljetaan pois tuotetaulukosta. Täsmälleen sama asia tapahtuu suoritettaessa relaatioalgebran luonnollista liitosoperaatiota. (Siellä on kuitenkin edelleen jonkin verran eroa luonnolliseen liittämiseen: SQL ei poista automaattisesti ylimääräistä WORKER_ID-saraketta). Näiden kahden taulukon täydellinen liitos lisäehdon BLDG_ID = 435 kanssa on esitetty kuvassa. 1. SELECT-komennon käyttäminen antaa lopulta seuraavan kyselytuloksen:

TAITOTYYPPI

Rappari

Katontekija

Sähköasentaja

Riisi. 1. Liittyminen TYÖNTEKIJÄ- ja TEHTÄVÄ-taulukoihin

Nyt näytämme sinulle, kuinka taulukko liitetään itseensä SQL:ssä.

Pyyntö: Listaa työntekijät heidän esimiesten nimeineen.

VALITSE A.WORKER_NAME, B.WORKER_NAME

TYÖNTEKIJÄLTÄ A, TYÖNTEKIJÄLTÄ B

WHERE B.WORKER_ID = A.SUPV_ID

Tämän esimerkin FROM-lause luo kaksi "kopiota" WORKER-taulukosta ja antaa niille aliakset A ja B. Alias ​​on taulukolle annettu vaihtoehtoinen nimi. Tämän jälkeen WORKER-taulukon kopiot A ja B yhdistetään WHERE-komennolla sillä ehdolla, että B:n TYÖNTUNNUS ja A:n SUPV_ID ovat yhtä suuret. Siten jokainen rivi A:sta liitetään riville B, joka sisältää tietoja rivinhallinnasta A (kuva 1). 2).

Riisi. 2. Kahden WORKER-taulukon kopion yhdistäminen

Valitsemalla kaksi työntekijän nimeä jokaiselta riviltä, ​​saamme tarvittavan luettelon:

A.NAMEB.NAME

M. Faraday H. Columbus

C.Nemo G.Rickover R.Garrett R.Garrett

P. Mason P. Mason G. Rickover G. Rickover H. Columbus H. Columbus J. Asianajaja P. Mason

Alias. Taulukolle annettu vaihtoehtoinen nimi.

A.WORKER_NAME edustaa työntekijää ja B.WORKER_NAME edustaa esimiestä. Huomaa, että jotkut työntekijät ovat omia esimiehiään, mikä seuraa heidän riveissään suoritetusta tasa-arvosta WORKER_ID - SUPV_ID.

SQL:ssä voit linkittää enemmän kuin kaksi taulukkoa kerrallaan:

Pyyntö

VALITSE WORKER_NAME

TYÖNTEKIJÄLTÄ, TEHTÄVÄSTÄ, RAKENTAMISTA

MISSÄ TYÖNTEKIJÄ.TYÖNTEKIJÄN_TUNNUS = TEHTÄVÄ.TYÖNTEKIJÄN_TUNNUS JA TEHTÄVÄ.BLDG_ID = RAKENNUS.BLDG_TUNNUS JA

TYPE = "toimisto"

Tulos:

M. Faraday

G. Rickover

J. Barrister

Huomaa, että jos sarakkeen nimi (esimerkiksi WORKER_ID tai BLDG_ID) esiintyy useammassa kuin yhdessä taulukossa, meidän on epäselvyyden välttämiseksi edeltävä sarakkeen nimi lähdetaulukon nimi. Mutta jos sarakkeen nimi esiintyy vain yhdessä taulukossa, kuten esimerkissämme TYPE, ei ole epäselvyyttä, joten taulukon nimeä ei tarvitse määrittää.

Tämän kyselyn SQL-komennot luovat yhden taulukon kolmesta relaatiotietokantataulukosta. Kaksi ensimmäistä taulukkoa yhdistetään WORKER_ID:llä, minkä jälkeen kolmas taulukko yhdistetään BLDG_ID:llä tuloksena olevaan taulukkoon. Kunto

TYPE = "toimisto"

WHERE-komento sulkee pois kaikki rivit paitsi toimistorakennuksiin liittyvät rivit. Tämä vastaa pyynnön vaatimuksia.

3. Alikyselyt

Alakysely. Pyyntö pyynnön sisällä

Alikysely voidaan sijoittaa kyselyn WHERE-lauseeseen, mikä laajentaa WHERE-lauseen ominaisuuksia. Harkitse esimerkkiä.

Pyyntö: Mitkä ovat rakennuksen 435 työntekijöiden erikoisalat?

VALITSE SKTLL_TYPE

TYÖNTEKIJÄLTÄ, MISSÄ WORKER_ID IN

(VALITSE WORKER_ID

WHERE BLDG_ID = 435)

Alikysely tässä esimerkissä

(VALITSE WORKER_ID

WHERE BLDG_ID = 435)

Alikyselyn sisältävää kyselyä kutsutaan ulkoinen pyyntö tai pääpyyntö. Alakysely johtaa seuraavan joukon työntekijätunnuksia:

TYÖNTEKIJÄN ID

ulkoinen pyyntö. Pääkysely, joka sisältää kaikki alikyselyt.

Tämä tunnusjoukko korvaa sitten alikyselyn ulkoisessa kyselyssä. Tästä eteenpäin ulompi kysely suoritetaan käyttämällä alikyselyn luomaa joukkoa. Ulompi kysely käsittelee WORKER-taulukon jokaisen rivin WHERE-lauseen mukaisesti. Jos rivin WORKER_ID on alikyselyn luomassa (IN)-joukossa, rivin TAITTOTYYPPI valitaan ja näytetään tuloksena olevassa taulukossa:

TAITOTYYPPI

Rappari

Katontekija

Sähköasentaja

On erittäin tärkeää, että alikyselyn SELECT-lause sisältää WORKER_ID:n ja vain WORKER_ID:n. Muussa tapauksessa ulkoisen kyselyn WHERE-lause, joka tarkoittaa, että WORKER_ID on työntekijätunnusten joukossa, ei olisi järkevä.

Huomaa, että alikysely voi loogisesti suorittaa ennen kuin pääkysely ottaa huomioon edes yhden rivin. Eräässä mielessä alikysely on riippumaton pääkyselystä. Se voidaan suorittaa täydellisenä kyselynä. Sanomme, että tällainen alikysely ei korreloi pääkyselyn kanssa. Kuten pian näemme, alikyselyt voidaan korreloida.

Korreloimaton alikysely. Alikysely, jonka arvo ei riipu mistään ulkoisesta kyselystä.

Tässä on esimerkki alikyselystä alikyselyn sisällä.

Pyyntö: Listaa toimistorakennuksiin määrätyt työntekijät.

Tarkastelemme jälleen kyselyä, jolla opimme yhteyden.

VALITSE WORKER_MAME

MISSÄ WORKER_ID IN

(VALITSE WORKER_ID

MISSÄ BLDG_ID IN

WHERE TYPE = "toimisto"))

Tulos:

M. Faraday

G. Rickover

J. Barrister

Huomaa, että meidän ei tarvitse kirjoittaa sarakkeiden nimien eteen missään taulukoiden nimiä, koska jokainen alikysely käsittelee yhden ja vain yhden taulukon, joten epäselvyyksiä ei voi olla.

Kysely suoritetaan järjestyksessä sisältä ulospäin. Toisin sanoen sisin kysely (tai "alin") suoritetaan ensin, sitten sen sisältävä alikysely ja sitten ulompi kysely.

Vastaavat alakyselyt. Kaikki edellä käsitellyt alikyselyt olivat riippumattomia pääkyselyistä, joissa niitä käytettiin. Riippumattomuudella tarkoitamme sitä, että alikyselyt voidaan suorittaa yksinään kokonaisina kyselyinä. Siirrymme nyt alikyselyjen luokkaan, jonka tulokset voivat riippua pääkyselyn tarkastelemasta rivistä. Tällaisia ​​alikyselyjä kutsutaan korreloiduiksi alikyselyiksi.

Korreloitu alikysely. Alikysely, jonka tulos riippuu pääkyselyn tarkastelemasta rivistä.

Pyyntö: Listaa työntekijät, joiden tuntipalkka on korkeampi kuin heidän esimiestensä.

VALITSE WORKER_NAME

MISSÄ A.HRLY_RATE >

(VALITSE B.HRLY_RATE

WHERE B.WORKER_ID = A.SUPV_ID)

Tulos:

Loogiset vaiheet tämän kyselyn suorittamiseksi ovat:

1. Järjestelmä luo kaksi kopiota TYÖNTEKIJÄ-taulukosta: kopio A ja kopio B. Niiden määrittelytavan mukaan A viittaa työntekijään, B johtajaan.

2. Järjestelmä tarkastelee sitten jokaista riviä A. Tämä rivi valitaan, jos se täyttää WHERE-lauseen. Tämä ehto tarkoittaa, että rivi valitaan, jos sen HRLY_RATE-arvo on suurempi kuin alikyselyn luoma HRLY_RATE.

3. Alikysely valitsee HRLY_RATE-arvon riviltä B, jonka WORKER_ID on yhtä suuri kuin rivin A SUPV_ID. Tämä hetki pääkyselyn mukaan. Tämä on johtajan HRLY_RATE.

Huomaa, että koska A.HRLY_RATE voidaan verrata vain yhteen arvoon, alikyselyn tulee palauttaa vain yksi arvo. Tämä arvo vaihtelee riippuen siitä, mitä riviä A tarkastellaan. Siten alikysely korreloi pääkyselyn kanssa. Näemme lisää esimerkkejä vastaavista alikyselyistä myöhemmin, kun tutkimme sisäänrakennettuja toimintoja.

EXISTS ja NOT EXISTS operaattorit

Oletetaan, että haluamme tunnistaa työntekijät, joita ei ole määrätty työskentelemään rakennuksessa. Pinnalla näyttää siltä, ​​että tällainen pyyntö voidaan tehdä helposti yksinkertaisesti kieltämällä pyynnön myönteinen versio. Oletetaan esimerkiksi, että olemme kiinnostuneita rakennuksesta, jonka BLDG_ID 435. Harkitse kyselyä:

VALITSE WORKER_ID

MISSÄ BLDG_ID EI 435

Valitettavasti tämä on ratkaisun väärä sanamuoto. Kysely antaa meille vain muissa rakennuksissa työskentelevien työntekijöiden tunnukset. Ilmeisesti osa niistä voidaan myös liittää rakennukseen 435.

Hyvin muotoiltu ratkaisu käyttää NOT EXISTS -operaattoria (ei ole olemassa):

VALITSE WORKER_ID

MISSÄ EI OLE OLEMASSA

WHERE ASSIGNMENT.WORKER_ID = TYÖNTEKIJÄ.TYÖNTUNNUS JA

Tulos:

WORKER_ID

EXISTS- ja NOT EXISTS -operaattorit sijoitetaan aina ennen alikyselyä. EXISTS arvo on tosi, jos alikyselyn luoma joukko ei ole tyhjä. Jos alikyselyn luoma joukko on tyhjä, EXISTS on epätosi. NOT EXISTS -operaattori toimii tietysti täsmälleen päinvastoin. Se on tosi, jos alikyselyn tulos on tyhjä, ja epätosi muuten.

OLEMASSA operaattori. Palauttaa tosi, jos tulosjoukko ei ole tyhjä.

EI OLE OLEMASSA operaattori. Palauttaa tosi, jos tulosjoukko on tyhjä.

Tässä esimerkissä olemme käyttäneet NOT EXISTS -operaattoria. Alikysely valitsee kaikki ne ASSIGNMENT-taulukon rivit, joissa TYÖNTEKIJÄN_ID on sama kuin pääkyselyssä tarkasteltu rivi ja BLDG_ID on 435. Jos tämä joukko on tyhjä, valitaan pääkyselyssä tarkasteltavan työntekijän rivi, koska tämä tarkoittaa, että tämä työntekijä ei työskentele rakennuksessa 435.

Ratkaisussamme käyttämällä korreloitua alikyselyä. Jos käytämme IN-operaattoria NOT EXISTS sijaan, voimme pärjätä korreloimattomalla alikyselyllä:

VALITSE WORKER_ID

MISSÄ WORKER_ID EI SISÄLLÄ

(VALITSE WORKER_ID

WHERE BLDG_ID = 435)

Tämä ratkaisu on yksinkertaisempi kuin ratkaisu NOT EXISTS -operaattorilla. Herää luonnollinen kysymys, miksi tarvitsemme OLEMASSA ja EI OLE ollenkaan. Vastaus on, että EI OLE OLEMASSA on ainoa tapa ratkaista kyselyt, jotka sisältävät sanan "kukin" ehdossa. Sellaiset kyselyt ratkaistaan ​​relaatioalgebrassa jakooperaatiolla ja relaatiolaskennassa yleisellä kvantorilla. Tässä on esimerkki kyselystä, joka sisältää sanan "jokainen" ehdossa:

Pyyntö: Listaa kuhunkin rakennukseen määrätyt työntekijät.

Tämä kysymys voidaan toteuttaa SQL:ssä käyttämällä kaksoisnegatiota. Muotoilemme kyselyn uudelleen siten, että se sisältää kaksoisnegatiivisen:

Pyyntö: Listaa työntekijät kenelle Ei on rakennus, johon niitä ei ole määrätty.

Olemme korostaneet kaksinkertaista negatiivista. On selvää, että tämä kysely on loogisesti sama kuin edellinen.

Nyt haluamme muotoilla ratkaisun SQL:llä. Jotta lopullisen ratkaisun ymmärtäminen olisi helpompaa, annamme ensin ratkaisun alustavaan ongelmaan: ongelmaan tunnistaa kaikki rakennukset, joita varten hypoteettinen työntekijä "1234" Ei määrätty.

(I) VALITSE BLDG_ID

MISSÄ EI OLE OLEMASSA

TEHTÄVÄ.TYÖNTEKIJÄN_TUNNUS = 1234)

Olemme merkinneet tämän kyselyn (I), koska viittaamme siihen myöhemmin. Jos tätä pyyntöä täyttävää rakennusta ei ole, työntekijä 1234 määrätään jokaiseen rakennukseen ja siksi hän täyttää alkuperäisen pyynnön ehdot. Alkuperäisen kyselyn ratkaisemiseksi meidän on yleistettävä kysely (I) tietystä työntekijästä 1234 WORKER_ID-muuttujaan ja muutettava tämä muokattu kysely suuremman kyselyn alikyselyksi. Tässä on ratkaisu:

(II) VALITSE TYÖNTEKIJÄN_TUNNUS

MISSÄ EI OLE OLEMASSA

MISSÄ EI OLE OLEMASSA

WHERE ASSIGNMENT.BLDG_ID = RAKENNUS.BLDG_ID JA

TEHTÄVÄ.TYÖNTEKIJÄN_TUNNUS = TYÖNTEKIJÄN.TYÖNTUNNUS)

Tulos:

TYÖNTEKIJÄN ID

Huomaa, että neljänneltä kyselyriviltä (II) alkava alikysely on identtinen kyselyn (I) kanssa, jossa "1234" on korvattu TYÖNTEKIJÄN.TYÖNÄPPÄIN. Kysely (II) voidaan lukea seuraavasti:

Valitse WORKER_ID kohteesta WORKER, jos rakennuksessa ei ole WORKER_ID:tä.

Tämä vastaa alkuperäisen pyynnön ehtoja.

Näemme, että NOT EXISTS -operaattorilla voidaan muotoilla ne kyselyt, jotka vaativat jakooperaation relaatioalgebrassa ja universaalin kvantorin relaatiolaskennassa. Helppokäyttöisyyden kannalta NOT EXISTS -operaattori ei tarjoa mitään erityisiä etuja, eli SQL-kyselyt, jotka käyttävät NOT EXISTS kahdesti, eivät ole helpompia ymmärtää kuin relaatioalgebraratkaisut jakooperaatiolla tai relaatiolaskennan ratkaisut universaalilla kvantorilla. Lisää tutkimusta tarvitaan sellaisten kielirakenteiden luomiseksi, jotka mahdollistavat luonnollisemman tavan ratkaista tällaisia ​​kyselyitä.

Sisäänrakennetut toiminnot

Harkitse tämäntyyppisiä kysymyksiä:

Mitkä ovat enimmäis- ja minimituntipalkat? Kuinka monta päivää työntekijät työskentelevät keskimäärin rakennuksessa 435? Kuinka monta päivää on rakennuksen 312 rappaustöissä yhteensä? Kuinka monta eri erikoisalaa on olemassa?

Näihin kysymyksiin vastaaminen vaatii koontifunktioita, jotka tarkastelevat useita taulukon rivejä ja tuottavat yhden arvon. SQL:ssä on viisi tällaista funktiota, joita kutsutaan sisäänrakennetuiksi funktioiksi tai set Functions -funktioiksi. Nämä ovat funktiot SUM (summa), AVG (keskiarvo), COUNT (count), MAX (maksimi) ja MIN (minimi).

Inline-toiminto (asetustoiminto). Tilastollinen toiminto, joka toimii useilla riveillä: SUM (summa), AVG (keskiarvo), COUNT (laskenta), MAX (maksimi), MIN (minimi).

Pyyntö: Mitkä ovat enimmäis- ja minimituntipalkat?

VALITSE MAX(HRLY_RATE), MIN(HRLY_RATE)

Tulos: 17.40, 8.20

MAX toiminnot ja MIN toimivat yhdessä taulukon sarakkeessa. He valitsevat suurimman tai vähimmäisarvon kyseisestä sarakkeesta. Kyselyformulaatiomme ei sisällä WHERE-lausetta. Useimmissa pyynnöissä näin ei ehkä ole, kuten seuraava esimerkki osoittaa.

Pyyntö: Kuinka monta päivää työntekijät työskentelevät keskimäärin rakennuksessa 435?

VALITSE AVG (NUM_DAYS)

WHERE BLDG_ID=435

Tulos: 12.33

Pyyntö: Kuinka monta päivää on rakennuksen 312 rappaustöissä yhteensä?

VALITSE SUMMA (NUM_DAYS)

TEHTÄVÄSTÄ, TYÖNTEKIJÄ

MISSÄ TYÖNTEKIJÄ.TYÖNTEKIJÄN_TUNNUS = TEHTÄVÄ.TYÖNTEKIJÄN_TUNNUS JA

SKILL_TYPE = "Kipteri" JA

Tulos: 27

Ratkaisu käyttää liittämistä ASSIGNMENT- ja WORKER-taulukoiden välillä. Tämä on tarpeen, koska SKILL_TYPE on WORKER-taulukossa ja BLDG_ID on taulukossa ASSIGNMENT.

Pyyntö: Kuinka monta eri erikoisalaa on olemassa?

VALITSE COUNT (DISTINCT SKILL_TYPE)

Tulos: 4

Koska sama erikoisuus voidaan toistaa useilla eri riveillä, tässä kyselyssä on käytettävä DISTINCT (different) -avainsanaa, jotta järjestelmä ei laskeisi samaa erikoistyyppiä useammin kuin kerran. DISTINCT-operaattoria voidaan käyttää minkä tahansa sisäänrakennetun toiminnon kanssa, vaikka se on tietysti redundantti MAX- ja MIN-toimintojen kanssa.

ERITTÄVÄ. Operaattori, joka sulkee pois päällekkäiset rivit.

SUM- ja AVG-funktioita tulee käyttää vain numeeristen sarakkeiden kanssa. Muita toimintoja voidaan käyttää sekä numeeristen että merkkitietojen kanssa. Kaikkia funktioita paitsi COUNT voidaan käyttää laskettujen lausekkeiden kanssa. Esimerkiksi:

Pyyntö: Mikä on keskimääräinen viikkopalkka?

VALITSE AVG(40*HRLY_RATE)

Tulos: 509.14

COUNT voi viitata koko riviin, ei vain yhteen sarakkeeseen :

Pyyntö: Kuinka monessa rakennuksessa on laatutaso 3?

SELECT COUNT (*)

RAKENTAMISTA MISSÄ

Tulos: 3

Kuten kaikki nämä esimerkit osoittavat, jos SELECT-komennossa on sisäänrakennettu toiminto, tässä SELECT-komennossa ei voi olla mitään muuta. Ainoa poikkeus tähän sääntöön on GROUP BY -lause, jota tarkastelemme hetken kuluttua.

GROUP BY ja HAVING lauseita

Hallinnassa tarvitaan usein tilastotietoja kustakin ryhmästä useissa ryhmissä. Harkitse esimerkiksi seuraavaa kyselyä:

Pyyntö: Selvitä kunkin esimiehen enimmäistuntipalkka hänen alaistensa keskuudessa.

Tämän ongelman ratkaisemiseksi meidän on jaettava työntekijät ryhmiin johtajiensa mukaan. Sen jälkeen määritämme kunkin ryhmän maksimipanoksen. SQL:ssä se tehdään näin:

RYHMÄ SUPV_ID:N MUKAAN

Tulos:

SUPV_IDMAX(HRLY RATE)

Tätä kyselyä käsitellessä järjestelmä jakaa ensin WORKER-taulukon rivit ryhmiin seuraavan säännön mukaisesti. Rivit sijoitetaan samaan ryhmään, jos ja vain jos niillä on sama SUPV_ID. SELECT-lausetta sovelletaan sitten jokaiseen ryhmään. Koska tässä ryhmässä on vain yksi SUPV_ID-arvo, ryhmässä ei ole SUPV_ID-epäselvyyttä. Jokaiselle ryhmälle SELECT-käsky tulostaa SUPV_ID:n sekä laskee ja tulostaa MAX(HRLY_RATE)-arvon. Tulos on esitetty yllä.

SELECT-käskyssä, jossa on sisäänrakennetut funktiot, voi esiintyä vain sarakkeita, jotka sisältyvät GROUP BY -lauseeseen. Huomaa, että SUPV_ID:tä voidaan käyttää SELECT-käskyssä, koska se sisältyy GROUP BY -lauseeseen.

Lause GROUP BY. Osoittaa, että rivit tulee jakaa ryhmiin, joilla on määritettyjen sarakkeiden yhteiset arvot.

GROUP BY -lause antaa sinun suorittaa tiettyjä monimutkaisia ​​laskelmia. Saatamme esimerkiksi haluta selvittää näiden enimmäishintojen keskiarvon. Sisäänrakennettujen funktioiden laskutoimituksia on kuitenkin rajoitettu siinä mielessä, että sisäänrakennettujen funktioiden käyttö muiden sisäänrakennettujen funktioiden sisällä ei ole sallittua. Eli sellainen ilmaisu

AVG(MAX(HRLY_RATE))

kielletty. Tällaisen pyynnön täytäntöönpano koostuu kahdesta vaiheesta. Ensin meidän on asetettava enimmäistarjoukset uuteen taulukkoon ja toisessa vaiheessa laskettava niiden keskiarvo.

GROUP BY -komennolla voit käyttää WHERE-komentoa:

Pyyntö: Ota selvää jokaisesta rakennustyypistä keskitaso laatu rakennusten joukossa 1.

VALITSE TYYPPI, AVG (QLTY_LEVEL)

MISSÄ TILA = 1

Tulos:

TYPEAVG (QLTY_TASO)

Kauppa 1

Asuinrakennus 3

WHERE-lause suoritetaan ennen GROUP BY -komentoa. Siksi mikään ryhmä ei voi sisältää riviä, jonka tila on muu kuin 1. Status 1 -rivit ryhmitellään TYYPIN mukaan, ja sitten kuhunkin ryhmään sovelletaan SELECT-lauseketta.

Lause HAVING. Asettaa ehtoja ryhmille.

Voimme myös soveltaa ehtoja GROUP BY -lausekkeen luomiin ryhmiin. Tämä tehdään HAVING-lausekkeella. Oletetaan esimerkiksi, että päätämme täydentää jotakin edellisistä kyselyistä:

Pyyntö: Selvitä jokaiselle esimiehelle, jolla on useampi kuin yksi alainen, hänen alaistensa enimmäistuntipalkka.

Voimme heijastaa tätä ehtoa sopivalla HAVING-komennolla:

VALITSE SUPV_ID, MAX (HRLY_RATE)

TYÖRYHMÄSTÄ: SUPV_ID

OTTAA LASKU(*) > 1

Tulos:

SUPV_ID MAX (HRLY_RATE)

Ero WHERE- ja HAVING-lausekkeiden välillä on se, että WHERE koskee rivejä, kun taas HAVING koskee ryhmiä.

Kysely voi sisältää sekä WHERE- että HAVING-lauseen. Tässä tapauksessa WHERE-lause arvioidaan ensin, koska se arvioidaan ennen ryhmittelyä. Harkitse esimerkiksi seuraavaa muutosta aikaisempaan kyselyyn:

Pyyntö: Selvitä kunkin rakennustyypin osalta keskimääräinen laatutaso tilan 1 rakennusten kesken. Ota huomioon vain ne rakennustyypit, joiden enimmäislaatutaso ei ylitä 3:a.

VALITSE TYYPPI, AVG(QLTY_JLEVEL)

MISSÄ TILA = 1

ON MAX (QLTY_TASO)<= 3

Tulos:

TYPEAVG (QLTY_TASO)

Kauppa 1

Asuinrakennus 3

Huomaa, että alkaen FROM-lauseesta lauseet suoritetaan järjestyksessä ja sitten käytetään SELECT-lausetta. Esimerkiksi WHERE-lausetta sovelletaan BUILDING-taulukkoon, ja kaikki rivit, joiden STATUS ei ole 1, poistetaan. Loput rivit on ryhmitelty TYPE:n mukaan; kaikki rivit, joilla on sama TYPE-arvo, päätyvät samaan ryhmään. Tämä luo useita ryhmiä, yhden kullekin TYPE-arvolle. HAVING-lausetta sovelletaan sitten jokaiseen ryhmään, ja ryhmät, joiden laatutason enimmäisarvo on suurempi kuin 3, poistetaan. Lopuksi SELECT-lausetta sovelletaan muihin ryhmiin.

7. Sisäänrakennetut funktiot ja alikyselyt

Sisäisiä toimintoja voidaan käyttää vain SELECT-lauseessa tai HAVING-käskyssä. Sisäisen funktion sisältävä SELECT-lause voi kuitenkin olla osa alikyselyä. Harkitse esimerkkiä tällaisesta alikyselystä:

Pyyntö: Kenellä työntekijällä on keskimääräistä korkeampi tuntipalkka?

VALITSE WORKER_NAME

WHERE HRLY_RATE >

(VALITSE AVG(HRLY_RATE)

Tulos:

H. Columbus

Huomaa, että alikysely ei korreloi pääkyselyn kanssa. Alikysely palauttaa täsmälleen yhden arvon - keskimääräisen tuntihinnan. Pääkysely valitsee työntekijän vain, jos sen tarjous on suurempi kuin laskettu keskiarvo.

Vastaavat kyselyt voivat myös käyttää sisäänrakennettuja toimintoja:

Kysymys: Kenellä työntekijöistä on korkeampi tuntipalkka kuin saman esimiehen alaisten keskimääräinen tuntipalkka?

Tässä tapauksessa sen sijaan, että laskettaisiin yksi keskimääräinen tuntipalkka kaikille työntekijöille, meidän on laskettava keskimääräinen tuntipalkka jokaiselle samalle johtajalle raportoivalle työntekijäryhmälle. Lisäksi laskelma on tehtävä uudelleen jokaiselle pääkyselyssä huomioitulle työntekijälle:

VALITSE A. WORKER_NAME

SQL mahdollistaa kyselyjen sisäkkäisyyden. Tyypillisesti alikysely palauttaa yhden arvon, joka testataan sen selvittämiseksi, onko predikaatti tosi.

Hakuehtotyypit:
. Vertailu alikyselyn tulokseen (=, >=)
. Tarkistetaan, kuuluvatko alikyselyn tulokset (IN)
. Olemassaolotesti (EXISTS)
. Useita (kvantitatiivisia) vertailuja (ANY, ALL)

Huomautuksia sisäkkäisistä kyselyistä:
. Alikyselyn tulee valita vain yksi sarake (paitsi EXISTS-predikaattia sisältävä alikysely), ja sen tulostietotyypin on vastattava predikaatissa määritetyn arvon tietotyyppiä.
. Joissakin tapauksissa voit käyttää DISTINCT-avainsanaa varmistaaksesi, että saat yhden arvon.
. Et voi sisällyttää ORDER BY- ja UNION-lauseita alikyselyyn.
. Alakysely voi näkyä joko hakutermin vasemmalla tai oikealla puolella.
. Alikyselyt voivat käyttää koontifunktioita ilman GROUP BY -lausetta, jotka palauttavat automaattisesti erityisarvon mille tahansa rivimäärälle, erityisen IN-predikaatin ja sarakkeisiin perustuvia lausekkeita.
. Aina kun mahdollista, tulee käyttää JOIN-taulukkoliitoksia alikyselyjen sijaan.

Esimerkkejä sisäkkäisistä kyselyistä:

SELECT * FROM Tilaukset WHERE SNum=(SELECT SNum FROM SalesPeople WHERE SName='Motika')
SELECT * FROM Tilaukset WHERE SNum IN (SELECT SNum FROM SalesPeople WHERE City='Lontoo')
SELECT * FROM Tilaukset WHERE SNum=(SELECT DISTINCT SNum FROM Tilaukset WHERE CNum=2001)
SELECT * FROM Tilaukset WHERE Amt>(SELECT AVG(Amt) FROM Tilaukset WHERE Päivämäärä=10/04/1990)
SELECT * FROM Customer WHERE CNum=(SELECT SNum+1000 FROM SalesPeople WHERE SName='Serres')

2) Aiheeseen liittyvät alikyselyt

SQL:ssä voit luoda alikyselyitä taulukkoviittauksella ulkoisesta kyselystä. Tässä tapauksessa alikysely suoritetaan useita kertoja, kerran jokaiselle ulkokyselyn taulukon riville. Siksi on tärkeää, että alikysely käyttää indeksiä. Alikysely voi viitata samaan taulukkoon kuin ulompi. Jos ulompi kysely palauttaa suhteellisen pienen määrän rivejä, siihen liittyvä alikysely toimii nopeammin kuin asiaankuulumaton. Jos alikysely palauttaa pienen määrän rivejä, siihen liittyvä kysely suoritetaan hitaammin kuin asiaankuulumaton.

Esimerkkejä aiheeseen liittyvistä alikyselyistä:

SELECT * FROM SalesPeople Main WHERE 1(SELECT AVG(Amt) FROM Tilaukset O2 WHERE O2.CNum=O1.CNum) //palauttaa kaikki tilaukset, jotka ovat suurempia kuin tämän asiakkaan keskimääräinen tilausarvo

3) EXISTS predikaatti

Syntaksimuoto: OLEMASSA ()

Predikaatti ottaa alikyselyn argumenttina ja arvioi arvoon tosi, jos alikyselyllä on tulos, muussa tapauksessa se evaluoi epätosi. Alikysely suoritetaan kerran ja se voi sisältää useita sarakkeita, koska niiden arvoja ei tarkisteta, mutta rivien läsnäolon tulos yksinkertaisesti korjataan.

Huomautuksia EXISTS-predikaatista:
. EXISTS on predikaatti, joka palauttaa TOSI tai EPÄTOSI ja jota voidaan käyttää yksinään tai muiden boolen lausekkeiden kanssa.
. EXISTS ei voi käyttää koontifunktioita alikyselyssään.
. Korreloiduissa (liittyvissä, riippuvaisissa - korreloiduissa) alikyselyissä EXISTS-predikaatti suoritetaan jokaiselle ulkotaulukon riville.
. Voit yhdistää EXISTS-predikaatin taulukkoliitoksilla.

Esimerkkejä EXISTS-predikaatista:

SELECT * FROM Customer WHERE EXISTS(SELECT * FROM Customer WHERE City='San Jose') – palauttaa kaikki asiakkaat, jos joku heistä asuu San Josessa.
SELECT DISTINCT SNum FROM Customer First WHERE NOT EXISTS (SELECT * FROM Customer Send WHERE Send.SNum=First.SNum AND Send.CNumFirst.CNum) - Palauttaa vain yhtä asiakasta palvelleiden myyjien lukumäärän.
SELECT DISTINCT F.SNum, SNum, F. City FROM myyntihenkilöstöltä F, Asiakkaalta S WHERE EXISTS (SELECT * FROM Customer T WHERE S.SNum=T.SNum JA S.CNumT.CNum JA F.SNum=S.SNum) - palauttaa kaikkien useita ostajia palvelleiden myyjien numerot, nimet ja asuinkaupungit.
SELECT * FROM SalesPeople Frst WHERE EXISTS (SELECT * FROM Customer Send WHERE Frst.SNum=Lähetä.SNum JA 1

4) Kvantitatiiviset vertailupredikaatit

Syntaksimuoto: (=|>|=|) KAIKKI|KAIKKI ()

Nämä predikaatit käyttävät alikyselyä argumenttina, mutta EXISTS-predikaattiin verrattuna niitä käytetään relaatiopredikaattien (=,>=) yhteydessä. Tässä mielessä ne ovat samanlaisia ​​kuin IN-predikaatti, mutta koskevat vain alikyselyitä. Standardi sallii SOME-avainsanan käytön ANY:n sijaan, mutta kaikki tietokantajärjestelmät eivät tue sitä.

Huomautuksia vertailupredikaateista:
. ALL-predikaatti arvioi arvoon TOSI, jos jokainen alikyselyn suorittamisen aikana valittu arvo täyttää ulkoisessa kyselypredikaatissa määritetyn ehdon. Useimmiten sitä käytetään eriarvoisuuksien kanssa.
. ANY-predikaatti arvioi arvoon TOSI, jos vähintään yksi alikyselyn suorittamisen aikana valittu arvo täyttää ulkoisessa kyselypredikaatissa määritetyn ehdon. Useimmiten sitä käytetään eriarvoisuuksien kanssa.
. Jos alikysely ei palauta rivejä, KAIKKI saa automaattisesti arvon TOSI (vertailuehdon katsotaan täyttyvän) ja KAIKKI - EPÄTOSI.
. Jos vertailu ei ole TOSI millekään riville ja siinä on yksi tai useampia nollarivejä, ANY palauttaa TUNTEMATTOMAN.
. Jos vertailu ei ole EPÄTOSI millekään riville ja siinä on yksi tai useampia nollarivejä, KAIKKI palauttaa TUNTEMATTOMAT.

Esimerkkejä kvantitatiivisesta vertailupredikaatista:

SELECT * FROM Sales People WHERE Kaupunki = KAIKKI(VALITSE kaupunki Asiakkaalta)
SELECT * FROM Tilaukset WHERE Amt ALL(VALITSE arvio asiakkaalta WHERE Kaupunki='Rooma')

5) Ainutlaatuisuuspredikaatti

AINUTLAATUINEN|ERILAINEN ()

Predikaattia käytetään alikyselyn tulosteen ainutlaatuisuuden (kaksoiskappaleiden puuttumisen) tarkistamiseen. Lisäksi UNIQUT-predikaatissa rivejä, joissa on NULL-arvot, pidetään ainutlaatuisina, ja DISTINCT-predikaatissa kahta nolla-arvoa pidetään samanarvoisina toistensa kanssa.

6) Vastaa predikaattia

OTTELU ()

MATCH-predikaatti testaa, vastaako kyselymerkkijonon arvo minkä tahansa alikyselystä palautetun merkkijonon arvoa. Tämä alikysely eroaa IN- ja ANY-predikaateista siinä, että sen avulla voit käsitellä "osittaisia" (PARTIAL) osumia, joita saattaa esiintyä riveissä, joilla on osa NULL-arvoista.

7) Pyynnöt LÄHETTÄJÄ-osiossa

Itse asiassa on hyväksyttävää käyttää alikyselyä aina, kun taulukkoviittaus on sallittu.

SELECT CName, Tot_Amt FROM Customer, (SELECT CNum, SUM(Amt) AS Tot_Amt FROM Orders GROUP BY CNum) WHERE Kaupunki='Lontoo' AND Customer.CNum=Tilaukset.CNum
//alikysely palauttaa kunkin Lontoosta ostajan tekemien tilausten kokonaismäärän.

8) Rekursiiviset kyselyt

REKURSIIVILLA
Q1 AS SELECT … FROM … MISSÄ …
Q2 AS SELECT … FROM … MISSÄ …




Ylös