MySQL Alikysely esimerkkien kanssa

โšก ร„lykรคs yhteenveto

MySQL Alikyselyn syntaksi sijoittaa yhden SELECT-lausekkeen toisen sisรครคn, joten sisempi tulos syรถttรครค ulkoista kyselyรค. Tรคmรค selitys kattaa skalaari-, rivi- ja taulukkoalikyselyt, suoritusjรคrjestyksen, kรคytรคnnรถn esimerkit ja suorituskyvyn kompromissin JOIN-operaatioita kรคytettรคessรค.

  • ๐Ÿ” Ydinmรครคritelmรค: Alikysely on toisen kyselyn sisรคllรค oleva SELECT-lauseke, ja sisempi kysely suoritetaan ensin syรถttรคmรครคn arvoja ulompaan kyselyyn.
  • ๐Ÿงฎ Skalaarinen alikysely: Palauttaa yhden rivin ja yhden sarakkeen, joten se toimii pareina vertailuoperaattoreiden, kuten yhtรค suuri kuin, suurempi kuin tai pienempi kuin, kanssa.
  • ๐Ÿ“‹ Rivi- ja taulukkoalikyselyt: Rivi-alikysely palauttaa yhden rivin, jossa on useita sarakkeita, kun taas taulukko-alikysely palauttaa useita rivejรค ja toimii IN-operaattorin kanssa.
  • ๐Ÿงฉ Pesรคsyvyys: Alikyselyitรค voidaan sisรคkkรคin sijoittaa useille tasoille, mikรค paikantaa arvoja, kuten eniten maksavan jรคsenen, yhdestรค lausekkeesta.
  • ๐Ÿ‡ง๐Ÿ‡ท SELECTin lisรคksi: INSERT-, UPDATE- ja DELETE-lausekkeet hyvรคksyvรคt alikyselyitรค, mikรค mahdollistaa joukkomuutokset ilman vรคliaikaisia โ€‹โ€‹taulukoita.
  • โšก Suorituskykysรครคntรถ: JOIN-kysely toimii yleensรค paljon nopeammin kuin vastaava alikysely, joten varaa alikyselyt logiikalle, jota JOIN ei voi ilmaista.

MySQL Alikysely

Mikรค on alikysely SQL:ssรค?

A alikysely on SELECT-kysely, joka on toisen kyselyn sisรคllรค. Sisรคistรค valintakyselyรค kรคytetรครคn yleensรค ulomman valintakyselyn tulosten mรครคrittรคmiseen, joten tietokanta arvioi ensin sisรคisen lausekkeen ja vรคlittรครค sitten sen tulosteen ylรถspรคin.

Sisรคistรค kyselyรค kutsutaan sisรคinen kysely tai sisรคkkรคinen kysely, ja sen sisรคltรคvรครค lauseketta kutsutaan ulkoinen kyselyTarkastellaanpa alikyselyn syntaksia.

MySQL Alikysely

Yllรค oleva kaavio nรคyttรครค lausekkeen yleisen muodon: ulompi SELECT antaa haluamasi sarakkeet ja hakasulkeissa oleva sisempi SELECT antaa arvon tai arvoluettelon, johon WHERE-lauseke vertaa.

Miksi kรคyttรครค alikyselyรค?

Ennen kuin tarkastellaan eri tyyppejรค, on hyรถdyllistรค tietรครค, milloin alikysely ansaitsee paikkansa lausekkeessa.

Alikysely vastaa kysymykseen, jonka suodatinarvoa ei tiedetรค etukรคteen. Se on laskettava itse datasta. Yleinen asiakasvalitus MyFlix-videokirjastossa on elokuvien vรคhรคinen mรครคrรค, ja johto haluaa ostaa elokuvia kategoriasta, jossa on vรคhiten nimikkeitรค. Kukaan ei tiedรค, mikรค kategoria se on, ennen kuin tietokannasta kysytรครคn, joten arvo on laskettava ensin ja sitten kรคytettรคvรค suodattimena.

Alikyselyt ovat osoitteessatrackolmesta kรคytรคnnรถn syystรค:

  • luettavuus: Jokainen logiikan osa sijaitsee omassa sulkeissa olevassa lohkossaan, joten lause on pikemminkin sarja pieniรค kysymyksiรค kuin yksi monimutkainen lauseke.
  • Eristรคminen: Sisรคinen kysely voidaan suorittaa yksinรครคn sen varmistamiseksi, ettรค se palauttaa odotetun arvon, mikรค helpottaa testausta ja virheenkorjausta huomattavasti.
  • Joustavuus: Sama kaava toimii WHERE-, HAVING-, SELECT- ja FROM-lausekkeissa sekรค INSERT-, UPDATE- ja DELETE-lausekkeissa.

Kompromissi on nopeus, jota tarkastellaan JOIN-vertailussa myรถhemmin tรคssรค artikkelissa.

Alikyselyiden tyypit MySQL

MySQL tukee kolmenlaisia โ€‹โ€‹alikyselyitรค, ja tyyppi mรครคrรคytyy sisรคisen kyselyn palauttaman tuloksen muodon mukaan. Jokainen tyyppi selitetรครคn alla toimivan esimerkin avulla myflixdb-tietokantaa vasten.

1) Skalaari-alikysely

A skalaarinen alikysely palauttaa tรคsmรคlleen yhden rivin ja yhden sarakkeen, mikรค tarkoittaa, ettรค se palauttaa yhden arvon. Koska tulos on yksi arvo, sitรค voidaan kรคyttรครค missรค tahansa, missรค literaaliarvo on sallittu. Palatakseni yllรค olevaan MyFlix-ongelmaan, voit kรคyttรครค seuraavanlaista kyselyรค:

SELECT category_name FROM categories
WHERE category_id = (SELECT MIN(category_id) FROM movies);

Se antaa tuloksen:

MySQL Alikysely

Katsotaanpa, miten tรคmรค kysely toimii.

MySQL Alikysely

Kuten toteutuskaaviosta nรคkyy, MySQL ensimmรคiset juoksut SELECT MIN(category_id) FROM movies, vastaanottaa yhden arvon ja suorittaa vasta sitten ulkoisen kyselyn kyseisen arvon kanssa. Koska palautetaan yksi arvo, sallitut operaattorit ovat vakiovertailujoukko: =, <> (Tai !=), >, >=, <ja <=.

๐Ÿ’ก Vinkki: Jos alikysely sijoitetaan jรคlkeen = palauttaa useamman kuin yhden rivin, MySQL aiheuttaa virheen 1242, Alikysely palauttaa useamman kuin yhden rivinVaihda operaattori asentoon IN, tai tiukenna sisรคistรค WHERE-lauseketta.

2) Rivi-alikysely

A rivin alikysely palauttaa myรถs yhden rivin, mutta kyseisellรค rivillรค voi olla useampi kuin yksi sarake. Ulompi kysely vertaa siis arvojen riviรค rivinmuodostajaan yksittรคisen arvon sijaan.

SELECT full_names, contact_number FROM members
WHERE (membership_number, gender) = (SELECT membership_number, gender FROM members WHERE full_names = 'Janet Jones');

Sallitut operaattorit ovat samat yllรค luetellut vertailuoperaattorit, joita sovelletaan koko riviin kerralla.

3) Taulukon alikysely

A taulukon alikysely palauttaa useita rivejรค ja usein useita sarakkeita, joten ulkokyselyssรค on kรคytettรคvรค joukko-operaattoria, kuten IN, NOT IN, ANY, ALLtai EXISTS.

Oletetaan, ettรค haluat niiden jรคsenten nimet ja puhelinnumerot, jotka ovat vuokranneet elokuvan eivรคtkรค ole vielรค palauttaneet sitรค, jotta voit soittaa heille muistutuksen antamiseksi. Voit kรคyttรครค seuraavanlaista kyselyรค:

SELECT full_names, contact_number FROM members
WHERE membership_number IN (SELECT membership_number FROM movierentals WHERE return_date IS NULL);

MySQL Alikysely

Katsotaanpa, miten tรคmรค kysely toimii.

MySQL Alikysely

Tรคssรค tapauksessa sisรคinen kysely palauttaa useamman kuin yhden tuloksen, joten jรคsennumeroiden luettelo luovutetaan IN operaattori ja jokainen vastaava jรคsen palautetaan.

Alikyselyiden sisรคkkรคisyys useilla tasoilla

Tรคhรคn mennessรค olet nรคhnyt kaksi tasoa. Alikysely voi sisรคltรครค myรถs toisen alikyselyn, joka tuottaa kolminkertaisen sisรคkkรคisen lausekkeen.

Oletetaan, ettรค johto haluaa palkita eniten maksavan jรคsenen. Voimme suorittaa seuraavanlaisen kyselyn:

SELECT full_names FROM members
WHERE membership_number = (SELECT membership_number FROM payments
    WHERE amount_paid = (SELECT MAX(amount_paid) FROM payments));

Sisimpรคnรค oleva kysely lรถytรครค suurimman maksun, keskimmรคisenรค kysely muuntaa kyseisen summan jรคsennumeroksi ja ulompana kysely muuntaa jรคsennumeron nimeksi. Yllรค oleva kysely antaa seuraavan tuloksen:

MySQL Alikysely

Alikyselyiden kรคyttรคminen INSERT-, UPDATE- ja DELETE-komentojen kanssa

Alikyselyt eivรคt rajoitu SELECT-lausekkeisiin. Sama hakasulkeissa oleva kaava toimii datanmuokkauslausekkeiden sisรคllรค, mikรค mahdollistaa kokonaisen rivijoukon muuttamisen yhdellรค kertaa ilman vรคliaikaisen taulukon luomista.

INSERT ja alikysely. Alikysely voi tarjota lisรคttรคvรคt rivit, jotka kopioivat tietoja taulukosta toiseen. SELECT-kyselyn sarakeluettelon on oltava linjassa INSERT-kyselyn sarakeluettelon kanssa.

INSERT INTO vip_members (membership_number, full_names)
SELECT membership_number, full_names FROM members
WHERE membership_number IN (SELECT membership_number FROM payments WHERE amount_paid > 5000);

Pร„IVITYS alikyselyllรค. Tรคssรค sisรคinen kysely pรครคttรครค, mitรค rivejรค kosketaan. Alla oleva esimerkki merkitsee jokaisen jรคsenen, jonka vuokraus on vielรค maksamatta.

UPDATE members
SET reminder_sent = 1
WHERE membership_number IN (SELECT membership_number FROM movierentals WHERE return_date IS NULL);

POISTA alikyselyllรค. Sama idea poistaa rivit, jotka tรคyttรคvรคt toisessa taulukossa olevan ehdon.

DELETE FROM members
WHERE membership_number NOT IN (SELECT membership_number FROM movierentals);

โš ๏ธ Varoitus: MySQL ei salli lausekkeen muokkaavan taulukkoa ja valitsevan samasta taulukosta FROM-lausekkeen alikyselyn sisรคllรค. Jos virhe 1093 ilmenee, rivitรค sisรคinen kysely johdettuun taulukkoon, esimerkiksi SELECT * FROM (SELECT ...) AS tSiten, ettรค MySQL materialisoi tuloksen ennen muutoksen kรคyttรถรถnottoa. On myรถs viisasta suorittaa ensin sisรคinen SELECT ja varmistaa rivien mรครคrรค ennen Pร„IVITYS tai POISTA tuotannossa.

Alikyselyt vs. liitokset

Sekรค alikysely ettรค JOIN voivat yhdistรครค tietoja useammasta kuin yhdestรค taulukosta, joten luonnollinen kysymys on, kumpaan niistรค kannattaa tarttua.

Liitoksiin verrattuna alikyselyt ovat helppokรคyttรถisiรค ja helppolukuisia. Ne eivรคt ole yhtรค monimutkaisia โ€‹โ€‹kuin Liitosten, ja siksi niitรค kรคytetรครคn usein mm. SQL-aloittelijat.

Mutta alikyselyillรค on suorituskykyongelmia. Liitoksen kรคyttรคminen alikyselyn sijaan voi joskus parantaa suorituskykyรค jopa 500-kertaisesti, koska optimoija voi ratkaista liitoksen yhdellรค kertaa sen sijaan, ettรค se arvioisi sisรคistรค lauseketta toistuvasti.

Vertailupiste Alikysely LIITY
luettavuus Korkea, koska jokainen lohko vastaa yhteen kysymykseen Alempi, koska kaikki taulukot nรคkyvรคt yhdessรค lausekkeessa
Suorituskyky Hitaampi, sisรคinen kysely saattaa suorittaa jokaisen ulkorivin Nopeammin, usein erittรคin suurella marginaalilla
Tulossarakkeet Vain ulomman taulukon sarakkeet palautetaan Jokaisen yhdistetyn taulukon sarakkeet voidaan palauttaa
Tyypillinen kรคyttรถ Suodatus ensin laskettavan arvon perusteella Yhdistรคmรคllรค toisiinsa liittyviรค rivejรค kahdesta tai useammasta taulukosta
Oppimiskรคyrรค Hellรคvarainen, aloittelijoille tuttu Jyrkempi, vaatii liitostyyppien tuntemusta

Jos valinta on annettu, on suositeltavaa kรคyttรครค JOIN-komentoa alikyselyssรค. Alikyselyitรค tulisi kรคyttรครค vararatkaisuna vain silloin, kun et voi kรคyttรครค JOIN-operaatiota edellรค mainitun saavuttamiseksi.

Alakyselyt vs liitokset

Alikyselyt on myรถs helppo jakaa yksittรคisiin loogisiin osiin, mikรค on erittรคin hyรถdyllistรค, kun testaus ja kyselyiden virheenkorjaus.

UKK

Korreloitu alikysely viittaa ulomman kyselyn sarakkeeseen, joten se arvioidaan kerran jokaista ulompaa riviรค kohden. Ei-korreloitu alikysely on itsenรคinen ja suoritetaan vain kerran. Korreloidut alikyselyt ovat tehokkaita, mutta huomattavasti hitaampia suurissa taulukoissa.

Alikysely voi sijaita WHERE-lausekkeessa, HAVING-lausekkeessa, SELECT-luettelossa tai FROM-lausekkeessa, joissa siitรค tulee johdettu taulukko ja se vaatii aliaksen. Se on kelvollinen myรถs INSERT-, UPDATE- ja DELETE-lausekkeiden sisรคllรค.

Usein kyllรค. Editoreihin sisรครคnrakennetut tekoรคlyavustajat, kuten MySQL Tyรถpรถytรค voi ehdottaa vastaavaa LIITYVertaa aina rivimรครคriรค ja lue EXPLAIN-suunnitelma ennen uudelleenkirjoitukseen luottamista, koska NULL-kรคsittely voi vaihdella.

Kyllรค. Tekstistรค SQL-avustajat muuttavat kysymyksen, kuten "missรค kategoriassa on vรคhiten elokuvia", sisรคkkรคiseksi SELECT-lausekkeeksi. Tarkkuus riippuu mallille toimitetusta kaavasta, joten vertaa luotua lauseketta todellisiin taulukoiden nimiin.

Virhe ilmenee, kun vertailuoperaattorin jรคlkeen sijoitettu alikysely palauttaa useita rivejรค. Korvaa operaattori IN-, ANY- tai EXISTS-operaattorilla tai tiivistรค sisรคistรค WHERE-lauseketta niin, ettรค palautetaan vain yksi rivi.

Tiivistรค tรคmรค viesti seuraavasti: