Ligzdoti un saistītie apakšvaicājumi SQL, predikāts EXISTS. Operatora EXISTS izmantošana Vaicājumi, izmantojot pastāvēšanas funkciju

KUR EKSISTĒ

Apakšvaicājumā tiek pārbaudīta vienas vai vairāku rindu klātbūtne. Ja vaicājumam atbilst vismaz viena rinda, tiek atgriezta Būla vērtība TRUE. Ja ir norādīts izvēles atslēgvārds NAV, Būla vērtība TRUE tiek atgriezta, ja apakšvaicājums neatgriež nevienu atbilstošu rindu.

apakšvaicājums

Pamatojoties uz pilnībā izveidoto apakšvaicājumu, tiek izgūta iegūtā datu kopa.

Vispārīgi noteikumi

Operators EXISTS pārbauda vienas vai vairāku rindu esamību vecāka vaicājuma apakšvaicājumā.

SELECT * FROM jobs WHERE NOT EXISTS (SELECT * FROM darbinieks WHERE jobs.job_id=employye.job_id);

Šis piemērs pārbauda ierakstu apakšvaicājumu, izmantojot papildu atslēgvārdu NOT. Tālāk sniegtajā piemērā apakšvaicājumā tiek meklēti konkrēti ieraksti, lai izgūtu galveno rezultātu kopu.

SELECT au_lname FROM authors WHERE EXISTS (SELECT * FROM publishers WHERE autori.pilsēta=izdevēji.pilsēta);

Šis vaicājums atgriež to autoru uzvārdus (au_lname), kuri dzīvo vienā pilsētā ar izdevējiem. Ņemiet vērā, ka apakšvaicājumā varat izmantot zvaigznīti, jo apakšvaicājumā ir jāatgriež tikai viens ieraksts ar Būla vērtību TRUE. Šādos gadījumos kolonnām nav nozīmes. Galvenais ir virknes esamība.

Daudzos vaicājumos operators EXISTS veic to pašu funkciju kā JEBKURS. Operators EXISTS parasti ir visefektīvākais, ja to izmanto ar saistītiem vaicājumiem.

Operators EXISTS ir semantiski līdzvērtīgs operatoram ANY.

Apakšvaicājums priekšrakstā EXISTS parasti veic vienu no diviem meklēšanas veidiem. Pirmā iespēja ir izmantot aizstājējzīmi - zvaigznīti (piemēram, SELECT * FROM...), tādā gadījumā jūs neizgūstat nevienu konkrētu kolonnu vai vērtību. Zvaigznīte šeit nozīmē "jebkuru kolonnu". Otrā iespēja ir atlasīt tikai vienu konkrētu kolonnu apakšvaicājumā (piemēram, SELECT aujd FROM). Dažas atsevišķas platformas atļauj veikt apakšvaicājumus vairākās kolonnās (piemēram, SELECT aujd, aujname FROM...). Tomēr šī funkcija ir reti sastopama, un no tās jāizvairās kodā, kas jāpārnes uz citām platformām.

Atšķirības starp platformām

Visas platformas atbalsta operatoru EXISTS iepriekš aprakstītajā formā.

“Iepriekš bija vieglāk” — es nodomāju, kad apsēdos, lai optimizētu nākamo vaicājumu SQL menedžmenta studija. Kad es rakstīju zem MySQL, viss bija patiešām vienkāršāk - tas vai nu darbojas, vai ne. Vai nu tas palēninās, vai ne. Paskaidrojums atrisināja visas manas problēmas, nekas vairāk nebija vajadzīgs. Tagad man ir jaudīga vide vaicājumu un procedūru/funkciju izstrādei, atkļūdošanai un optimizēšanai, un visa šī nekārtība, manuprāt, rada tikai vēl vairāk problēmu. Un kāpēc viss? Jo iebūvētais vaicājumu optimizētājs ir ļauns. Ja MySQL un PostgreSQL es rakstu

Atlasiet * no a, b, c, kur a.id = b.id, b.id = c.id

un katrā no planšetēm būs vismaz 5k rindas - viss sastings. Un paldies Dievam! Jo citādi izstrādātājam labākajā gadījumā rodas slinkums pareizi rakstīt, sliktākajā gadījumā viņš vispār nesaprot, ko dara! Galu galā tas pats vaicājums MSSQL darbosies līdzīgi

Atlasiet * no savienojuma b uz a.id = b.id savienojuma c uz b.id = c.id

Iebūvētais optimizētājs ķemmēs lieko pieprasījumu un viss būs kārtībā.

Viņš arī pats izlems, ko labāk darīt – pastāvēt vai pievienoties un daudz ko citu. Un viss darbosies pēc iespējas optimālāk.

Ir tikai viens BET. Vienā brīdī optimizētājs paklups sarežģīts vaicājums un pāriet, un tad jums rodas milzīga problēma. Un to var nesaņemt uzreiz, bet tad, kad tabulu svars sasniegs kritisko masu.

Tātad, lūk, raksta būtība. pastāv un tiek veiktas ļoti smagas operācijas. Tas faktiski ir atsevišķs apakšvaicājums katram rezultātu līnijas. Un, ja ir arī ligzdošana, tad tas parasti izslēdz gaismas. Viss būs ok, kad tiks atgrieztas 1, 10, 50 rindas. Jūs nejutīsit atšķirību, un, iespējams, pievienošanās būs vēl lēnāka. Bet, kad 500 izvelk, sākas problēmas. 500 apakšvaicājumi vienā pieprasījumā ir nopietni.

Lai gan no cilvēka izpratnes viedokļa in un theres ir labāki, taču no laika izmaksu viedokļa vaicājumiem, kas atgriež 50+ rindas, tie nav pieņemami.

Jāpieliek atruna, ka, dabiski, ja kaut kur samazinās, tad kaut kur jāierodas. Jā, pievienošanās prasa vairāk atmiņas, jo visas vērtību tabulas glabāšana vienlaikus un darbība ar to ir dārgāka nekā katras rindas apakšvaicājumu izpilde, ātri atbrīvojot atmiņu. Īpaši jāizskata pieprasījums un jāizmēra, vai papildu atmiņas izmantošana laika dēļ būs kritiska vai nē.

Es sniegšu pilnīgu analoģiju piemērus. Vispārīgi runājot, es vēl neesmu saskāries ar tik sarežģītām vaicājumiem, ko nevarētu izvērst savienojumu kaskādē. Tas var aizņemt dienu, bet viss var tikt atklāts.

Atlasiet * no a kur a.id iekšā (izvēlieties id no b) atlasiet * no a, kur pastāv (atlasiet augšējo 1 1 no b, kur b.id = a.id) atlasiet * no savienojuma b uz a.id = b. id atlasiet * no a kur a.id nav (izvēlieties id no b) atlasiet * no a, kur neeksistē (atlasiet augšējo 1 1 no b, kur b.id = a.id) atlasiet * no kreisā savienojuma b uz a. id = b.id, kur b.id ir nulle

Es atkārtoju - MSSQL optimizētājs optimizē šos piemērus maksimālā veiktspēja un nekad nebūs stulbu cilvēku ar tik vienkāršiem lūgumiem.

Tagad apskatīsim piemēru reālam vaicājumam, kas bija jāpārraksta, jo tas vienkārši sastinga uz dažiem paraugiem (struktūra ir ļoti vienkāršota un jēdzieni ir aizstāti, nav jābaidās no datu bāzes struktūras neoptimalitātes ).

Jums ir jāizvelk visi dublētie “produkti” dažādos kontos, koncentrējoties uz produkta parametriem, tā grupu un vecākgrupu, ja tāda ir.

Atlasiet d.PRODUCT_ID no PRODUCT s, PRODUCT_GROUP sg pa kreisi pievienoties M_PG_DEPENDENCY sd on (sg.PRODUCT_GROUP_ID = sd.M_PG_DEPENDENCY_CHILD_ID), PRODUCT d, PRODUCT_GROUP dg pa kreisi pievienoties M_PG_DEPENDENCY dd.DEYM. ILD_ID), kur s.PRODUCT_GROUP_ID=sg .PRODUCT_GROUP_ID un d.PRODUCT_GROUP_ID=dg.PRODUCT_GROUP_ID un sg.PRODUCT_GROUP_PERSPEC=dg.PRODUCT_GROUP_PERSPEC un sg.PRODUCT_GROUP_NAME=dg.PRODUCT_GROUP_NAME un s.PRODUCT_NAME=d.PRODUCT_NAME un s.PRODUCT_TYPE=d.CUCUSE_PRODUCT_TYPE un.REISSEIS. un s.PRODUCT_MULTISELECT=d.PRODUCT_MULTISELECT un dg.PRODUCT_GROUP_IS_TMPL=0 un ((sd.M_PG_DEPENDENCY_CHILD_ID ir nulle un dd.M_PG_DEPENDENCY_CHILD_ID ir nulle) vai eksistē (atlasiet 1 no PRODUCT_GROUPs.GPG_1, PRODUCT_GROUPsd1, PARENT_ID = sg1.PRODUCT_GROUP_ID un dd .M_PG_DEPENDENCY_PARENT_ID = dg1.PRODUCT_GROUP_ID un sg1.PRODUCT_GROUP_PERSPEC=dg1.PRODUCT_GROUP_PERSPEC un sg1.PRODUCT_GROUP_NAME=dg1.PRODUCT_GROUP_NAME un))

Tātad šis ir gadījums, kad optimizētājs padevās. Un katrai rindai tika izpildīta smaga eksistence, kas nogalināja datubāzi.

Atlasiet d.PRODUCT_ID no PRODUCT s pievienoties PRODUCT d uz s.PRODUCT_TYPE=d.PRODUCT_TYPE un s.PRODUCT_NAME=d.PRODUCT_NAME un s.PRODUCT_IS_SECURE=d.PRODUCT_IS_SECURE un s.PRODUCT_MULTISELECT=d.PRODUCT_MULTISELECT pievienoties PRODUCT_ID_GROUP_sg on sg.PRODUCT_GROUP_ID pievienoties PRODUCT_GROUP dg uz d.PRODUCT_GROUP_ID=dg.PRODUCT_GROUP_ID un sg.PRODUCT_GROUP_NAME=dg.PRODUCT_GROUP_NAME un sg.PRODUCT_GROUP_PERSPEC=dg.PRODUCT_GROUP_PERSPEC pa kreisi pievienoties M_GROUP_GROUPs =ENCHSENDPPYPG_DEPEND ENCY sd uz d. ID pa kreisi pievienoties M_PG_DEPENDENCY dd uz dg. PRODUCT_GROUP_ID = dd.M_PG_DEPENDENCY_CHILD_ID atlicis pievienoties PRODUCT_GROUP sgp uz sgp.PRODUCT_GROUP_ID = sd.M_PG_DEPENDENCY_PARENT_ID pa kreisi pievienoties PRODUCT_GROUP dgp uz dgp.PRODUCT_GROUP_PROPG_DEPENTY_sgp.p. NAME = dgp.PRODUCT_GROUP_NAME un isnull(sgp.PRODUCT_GROUP_IS_TMPL, 0) = isnull( dgp. PRODUCT_GROUP_IS_TMPL, 0), kur (sd.M_PG_DEPENDENCY_CHILD_ID ir nulle un dd.M_PG_DEPENDENCY_CHILD_ID ir nulle) vai (sgp.PRODUCT_GROUP_NAME nav nulle un dgp.PRODUCT_GROUP_NAME nav nulle)

Pēc šīm pārvērtībām skata veiktspēja eksponenciāli palielinājās līdz ar atrasto produktu skaitu. Pareizāk sakot, meklēšanas laiks palika praktiski neatkarīgs no sakritību skaita un vienmēr bija ļoti mazs. Kā tam jābūt.

Šis ir uzskatāms piemērs tam, kā uzticēšanās MSSQL optimizētājam var izspēlēt nežēlīgu joku. Neuzticieties viņam, neesiet slinks, pievienojieties manuāli, katru reizi padomājiet, kas ir labāk konkrētajā situācijā - pastāv, vai pievienojies.

SQL valodas predikāts EXISTS veic loģisku uzdevumu. IN SQL vaicājumišis predikāts tiek lietots formas izteiksmēs

PASTĀV (ATLASĪT * NO TABLE_NAME...).

Šī izteiksme atgriež vērtību “true”, ja vaicājums atrod vienu vai vairākas rindas, kas atbilst nosacījumam, un atgriež vērtību “false”, ja rinda netiek atrasta.

Attiecībā uz NOT EXISTS ir otrādi. Izteiksme

NEPASTĀV (ATLASĪT * NO TABLE_NAME...)

atgriež true, ja vaicājumā nav atrasta neviena rinda, un false, ja ir atrasta vismaz viena rinda.

Vienkāršākie vaicājumi ar predikātu SQL EXISTS

Piemēros mēs strādājam ar bibliotēkas datu bāzi un tās tabulām “Lietojamā grāmata” (BOOKINUSE) un “Lietotājs” (LIETOTĀJS). Pagaidām mums ir nepieciešama tikai tabula “Lietojamā grāmata” (BOOKINUSE).

AutorsNosaukumsPubyearInv_NrLietotāja ID
TolstojsKarš un miers2005 28 65
ČehovsĶiršu dārzs2000 17 31
ČehovsAtlasīti stāsti2011 19 120
ČehovsĶiršu dārzs1991 5 65
Ilfs un PetrovsDivpadsmit krēsli1985 3 31
MajakovskisDzejoļi1983 2 120
pastinaksĀrsts Živago2006 69 120
Tolstojssvētdiena2006 77 47
TolstojsAnna Kareņina1989 7 205
PuškinsKapteiņa meita2004 25 47
GogolisLugas2007 81 47
ČehovsAtlasīti stāsti1987 4 205
pastinaksIzlase2000 137 18

1. piemērs. Nosakiet to lietotāju ID, kuriem tika dotas Tolstoja grāmatas un kuriem tika dotas arī Čehova grāmatas. Ārējais vaicājums atlasa datus par lietotājiem, kuriem tika dotas Tolstoja grāmatas, un predikāts EXISTS norāda papildu nosacījumu, kas tiek pārbaudīts iekšējā vaicājumā - lietotāji, kuriem tika dotas Čehova grāmatas. Papildu nosacījums iekšējā pieprasījumā ir tāds, ka lietotāju ID no ārējiem un iekšējiem pieprasījumiem atbilst: User_ID=tols_user.user_id. Pieprasījums būs šāds:

Šis vaicājums atgriezīs šādu rezultātu:

Atšķirības starp EXISTS un IN predikātiem

No pirmā acu uzmetiena uz vaicājumiem ar predikātu EXISTS var rasties iespaids, ka tas ir identisks predikāts IN. Tas ir nepareizi. Lai gan tie ir ļoti līdzīgi. IN predikāts meklē vērtības no tā argumentā norādītā diapazona, un, ja tādas ir, tiek atlasītas visas rindas, kas atbilst šim diapazonam. Predikāta EXISTS rezultāts ir “jā” vai “nē” atbilde uz jautājumu, vai vispār ir vērtības, kas atbilst argumentā norādītajām vērtībām. Turklāt IN predikāta priekšā ir kolonnas nosaukums, pēc kuras meklēt rindas, kas atbilst diapazona vērtībām. Apskatīsim piemēru, kas parāda atšķirību starp predikātu EXISTS un IN predikātu, kā arī problēmu, kas atrisināta, izmantojot IN predikātu.

4. piemērs. Nosakiet to lietotāju ID, kuriem grāmatas ir izsnieguši autori, kuru grāmatas ir izsniegtas lietotājam ar ID 31. Pieprasījums būs šāds:

Lietotāja ID
120
65
205

Iekšējā vaicājumā (pēc IN) tiek atlasīti autori: Čehovs; Ilfs un Petrovs. Ārējais vaicājums atlasa visus lietotājus, kuriem ir izdotas šo autoru grāmatas. Redzam, ka atšķirībā no predikāta EXISTS, IN predikāta priekšā ir kolonnas nosaukums, šajā gadījumā - Autors.

Vaicājumi ar EXISTS predikātu un papildu nosacījumiem

Ja papildus predikātam EXISTS vaicājumā lietojat vismaz vienu papildu nosacījumu, piemēram, kas norādīts, izmantojot summētās funkcijas, tad šādi vaicājumi var kalpot vienkāršai datu analīzei. Pierādīsim to ar šādu piemēru.

5. piemērs. Nosakiet to lietotāju ID, kuriem Pasternak ir izsniedzis vismaz vienu grāmatu un vairāk nekā 2 grāmatas. Mēs rakstām šādu vaicājumu, kurā pirmo nosacījumu norāda predikāts EXISTS ar ligzdotu vaicājumu, bet otrajam nosacījumam ar operatoru HAVING vienmēr jānāk aiz ligzdotā vaicājuma:

Pieprasījuma rezultāts:

Lietotāja ID
120

Kā redzams no BOOKINUSE tabulas, Pasternaka grāmata tika izsniegta arī lietotājam ar ID 18, taču viņam tika dota tikai viena grāmata un tā nav iekļauta paraugā. Ja līdzīgam vaicājumam vēlreiz lietojat funkciju COUNT, bet šoreiz, lai saskaitītu atlasītās rindas (praktizēt to pats), varat iegūt informāciju par to, cik lietotāju, kuri lasa Pasternaka grāmatas, lasa arī citu autoru grāmatas. Tas jau ir no datu analīzes jomas.

Vaicājumi ar predikātu EXISTS divās tabulās

Vaicājumi ar predikātu EXISTS var izgūt datus no vairāk nekā vienas tabulas. Daudzas problēmas var atrisināt ar tādu pašu rezultātu, izmantojot JOIN operators, taču dažos gadījumos, izmantojot EXISTS, varat izveidot mazāk apgrūtinošu vaicājumu. Vēlams izmantot EXISTS gadījumos, kad iegūtajā tabulā būs kolonnas tikai no vienas tabulas.

Nākamajā piemērā no tās pašas datu bāzes papildus tabulai BOOKINUSE jums būs nepieciešama arī tabula USER.

Vaicājuma rezultāts būs šāda tabula:

Autors
Čehovs
Majakovskis
pastinaks

Tāpat kā izmantojot operatoru JOIN, gadījumos, kad ir vairāk nekā viena tabula, izmantojiet tabulu aizstājvārdus, lai pārbaudītu, vai tabulas savienojošo atslēgu vērtības atbilst. Mūsu piemērā tabulu aizstājvārdi ir bk un us, un atslēga, kas savieno tabulas, ir User_ID.

PASTĀV predikāts vairāk nekā divu tabulu savienojumos

Tagad mēs redzēsim sīkāk, kāpēc ir vēlams izmantot EXISTS gadījumos, kad iegūtajā tabulā būs kolonnas tikai no vienas tabulas.

Strādājam ar "Nekustamā īpašuma" datubāzi. Darījumu tabulā ir dati par darījumiem. Mūsu uzdevumiem šajā tabulā būs svarīga kolonna Tips ar datiem par darījuma veidu - pārdošana vai noma. Objektu tabulā ir dati par objektiem. Šajā tabulā mums būs nepieciešamas kolonnu Istabas (istabu skaits) un LogBalc vērtības, kurās ir dati par lodžijas vai balkona esamību Būla formātā: 1 (jā) vai 0 (nē). Tabulās Klients, Pārzinis un Īpašnieks satur datus attiecīgi par klientiem, uzņēmumu vadītājiem un īpašumu īpašniekiem. Šajās tabulās FName un LNname ir attiecīgi vārds un uzvārds.

7. piemērs. Identificējiet klientus, kuri ir iegādājušies vai īrējuši īpašumus, kuriem nav lodžijas vai balkona. Mēs rakstām šādu vaicājumu, kurā predikāts EXISTS norāda piekļuvi divu tabulu savienošanas rezultātam:

Tā kā kolonnas tiek atlasītas no tabulas Klients, izmantojot zvaigznītes operatoru, tiks parādītas visas šīs tabulas kolonnas, kurās būs tik daudz rindu, cik ir klientu, kas atbilst predikāta EXISTS norādītajam nosacījumam. Mums nav jāizvada kolonnas no tabulām, kuru savienojumam piekļūst apakšvaicājums. Tāpēc, lai ietaupītu mašīnas laiku, tiek izgūta tikai viena kolonna. Lai to izdarītu, aiz vārda SELECT tiek ierakstīta vienība. Tāda pati tehnika tiek izmantota vaicājumos turpmākajos piemēros.

Pats uzrakstiet SQL vaicājumu ar predikātu EXISTS un pēc tam skatiet risinājumu

Mēs turpinām rakstīt SQL vaicājumus kopā ar predikātu EXISTS

9. piemērs. Noteikt iznomāto objektu īpašniekus. Mēs rakstām šādu vaicājumu, kurā predikāts EXISTS arī norāda piekļuvi divu tabulu savienošanas rezultātam:

Tāpat kā iepriekšējā piemērā, tiks atgriezti visi tabulas lauki, kuriem piekļūst ārējais vaicājums.

10. piemērs. Nosakiet īpašnieku skaitu, kuru īpašumos rīkojās pārvaldnieks Saveļjevs. Mēs rakstām vaicājumu, kurā ārējais vaicājums piekļūst trīs tabulu savienojumam, un predikāts EXISTS norāda piekļuvi tikai vienai tabulai:

Visi vaicājumi tiek pārbaudīti, salīdzinot ar esošu datu bāzi. Veiksmīga lietošana!

Relāciju datu bāzes un SQL valoda

Novosibirskas Valsts ekonomikas un vadības akadēmija

DISCIPLINAS LABORATORIJAS PRAKTIKA

"DATU BĀZE"

Laboratorijas darbs Nr.7

"Bāzu valoda SQL dati: datu manipulācijas komandas»

NOVOSIBIRSKA 2000

SQL ir strukturētās vaicājumu valodas saīsinājums. No valodas nosaukuma ir skaidrs, ka tās galvenais mērķis ir ģenerēt vaicājumus, lai iegūtu informāciju no datu bāzes. Datu izguves komandas veido datu apstrādes valodas DML – SQL valodas neatņemama sastāvdaļa – pamatu. Tomēr DML sastāv vairāk nekā tikai komandas datu izgūšanai no datu bāzes. Ir arī komandas datu modificēšanai, datu pārvaldībai un citām.

Laboratorijas darbā tiek apskatīti DML valodas pamatrīki. Notiek laboratorijas darbi mēs pieturēsimies pie SQL2 standarta.

Sakarā ar to, ka SQL ir liela valoda, mēs apsvērsim tikai pamata komandas. Turpmākajās laboratorijās ir apskatīti dažādi specifiski SQL rīki.

Laboratorijas darbu veikšanai nepieciešamas zināšanas par relāciju datu modeļa pamatiem, relāciju algebras un relāciju aprēķinu pamatiem un principiem darbā ar MS SQL Server DBVS.

Laboratorijas darbu veikšanas rezultātā apgūsiet datu manipulācijas metodes, izmantojot SQL valodas komandas, apskatīsiet MS SQL Server DBVS realizētās valodas dialektu.

IEVADS

SQL satur plašu datu apstrādes iespēju klāstu gan vaicājumu veidošanai, gan datu bāzes atjaunināšanai. Šīs iespējas ir atkarīgas tikai no datu bāzes loģiskās struktūras, nevis uz tās fizisko struktūru, kas atbilst relāciju modeļa prasībām.

Sākotnējā SQL sintakses struktūra bija (vai vismaz šķita, ka tā bija) balstīta uz Koda relāciju aprēķinu. Vienīgā atbalstītā darbība relāciju algebrā bija savienība.

Papildus relāciju aprēķiniem līdzīgajai sintaksei, kas izstrādāta iepriekšējā standartā, SQL2 tieši ievieš operāciju apvienošanu, krustojumu, atšķirību un pievienošanos. Atlasīšanas, projektu un produktu darbības tika (un joprojām tiek) atbalstītas gandrīz tieši, savukārt sadalīšanas un piešķiršanas darbības tiek atbalstītas apgrūtinošākā veidā.

Vispirms aprakstīsim SQL vaicājumu valodu un pēc tam tās datu ievades un modifikācijas darbības. Datu modifikācijas darbības tiks aprakstītas pēdējās, jo to struktūra zināmā mērā ir atkarīga no vaicājuma valodas struktūras.

Vienkārši vaicājumi

Priekš mums vienkāršs pieprasījums būs vaicājums, kas piekļūst tikai vienai tabulai datu bāzē. Vienkārši vaicājumi palīdzēs mums ilustrēt SQL pamatstruktūru.

Vienkāršs pieprasījums. Vaicājums, kas piekļūst tikai vienai datu bāzes tabulai.

Pieprasīt: Kas strādā par apmetēju?

WHERE SKILL_TYPE = "apmetējs"

Rezultāts:

G.Rikovers

Šis vaicājums ilustrē trīs visizplatītākos frāzes SQL: SELECT, FROM un WHERE. Lai gan mūsu piemērā mēs tos ievietojām dažādās rindās, tie visi var parādīties vienā rindā. Tiem var būt arī atšķirīga atkāpe, un vārdus frāzēs var atdalīt ar patvaļīgu atstarpju skaitu. Apskatīsim katras frāzes īpašības.

Izvēlieties. Klauzulā SELECT ir norādītas kolonnas, kurām jāparādās iegūtajā tabulā. Tās vienmēr ir kādas relāciju tabulas kolonnas. Mūsu piemērā iegūtā tabula sastāv no vienas kolonnas (NAME), bet kopumā tajā var būt vairākas kolonnas; tajā var būt arī aprēķinātas vērtības vai konstantes. Mēs sniegsim piemērus katrai no šīm iespējām. Ja iegūtajā tabulā ir jābūt vairāk nekā vienai kolonnai, visas vajadzīgās kolonnas tiek uzskaitītas pēc tam SELECT komandas atdalītas ar komatiem. Piemēram, frāze SELECT WORKER_ID, NAME radīs tabulu, kas sastāv no kolonnām WORKER_ID un NAME.

SELECT klauzula. Norāda iegūtās tabulas kolonnas.

No. FROM klauzula norāda vienu vai vairākas tabulas, kurām piekļūst vaicājums. Visām kolonnām, kas norādītas klauzulā SELECT un WHERE, ir jābūt vienā no komandā FROM norādītajām tabulām. SQL2 šīs tabulas var tieši definēt shēmā kā bāzes tabulas vai datu skatus, vai arī tās pašas var būt nenosauktas tabulas, kas izriet no SQL vaicājumiem. Pēdējā gadījumā pieprasījums ir skaidri norādīts komandā FROM.

FROM frāze. Norāda esošās tabulas, kurām piekļūst vaicājums.

Kur. Klauzula WHERE satur nosacījumu. uz kuru pamata tiek atlasītas tabulas(-u) rindas. Mūsu piemērā nosacījums ir tāds, ka kolonnā SKILL_TYPE ir jābūt konstantei "Plasterer", kas ir ietverta apostrofos, kā tas vienmēr tiek darīts ar teksta konstantēm SQL. WHERE klauzula ir nepastāvīgākā SQL komanda; tajā var būt daudz dažādu nosacījumu. Liela daļa mūsu diskusiju tiks veltīta dažādu WHERE komandā atļauto konstrukciju ilustrēšanai.

KUR klauzula. Norāda nosacījumu, pamatojoties uz kuru rindas tiek atlasītas no norādītajām tabulām.

Iepriekš minēto SQL vaicājumu sistēma apstrādā šādā secībā: FROM, WHERE, SELECT. Tas nozīmē, ka FROM komandā norādītās tabulas rindas tiek ievietotas darba zonā apstrādei. Pēc tam klauzula WHERE tiek piemērota katrai rindai pēc kārtas. Visas rindas, kas neatbilst WHERE nosacījumam, tiek izslēgtas no izskatīšanas. Pēc tam tās rindas, kas atbilst WHERE nosacījumam, tiek apstrādātas ar priekšrakstu SELECT. Mūsu piemērā NAME ir atlasīts no katras šādas rindas, un visas atlasītās vērtības tiek izvadītas kā vaicājuma rezultāti.

Pieprasīt: Sniedziet visu informāciju par biroju ēkām.

WHERE TYPE = "birojs"

Rezultāts:

BLDG IDADDRESSTYPEQLTY LEVELSTATUS

312 Elm St., 123 Office 2 2

210 Berezovaya st. 1011 Office Z 1

111 Osinovaya st. 1213 Office 4 1

Zvaigznīte (*) komandā SELECT nozīmē “visu rindu”. Šis ir ērts saīsinājums, ko mēs bieži izmantosim.

Pieprasīt: Kāda ir katra elektriķa nedēļas alga?

IZVĒLIES NOSAUKUMU, "Nedēļas alga = ", 40 * HRLY_RATE

WHERE SKILL_TYPE = "elektriķis"

Rezultāts:

M. Faraday Iknedēļas alga = 500,00

H.Kolumbs Iknedēļas alga = 620,00

Šis vaicājums ilustrē gan rakstzīmju konstantu (mūsu piemērā "Nedēļas alga = "), gan aprēķinu izmantošanu komandā SELECT. Priekšraksta SELECT ietvaros varat veikt aprēķinus, kuros tiek izmantotas ciparu kolonnas un skaitliskās konstantes, kā arī standarta aritmētiskos operatorus ( +, -, *, /), sagrupēti pēc vajadzības, izmantojot iekavas. Esam iekļāvuši arī jaunu ORDER komanda BY, kas kārto vaicājuma rezultātu augošā burtciparu secībā pēc norādītās kolonnas. Ja vēlaties kārtot rezultātus dilstošā secībā, komandai jāpievieno DESC. Klauzula ORDER BY var kārtot rezultātus pēc vairākām kolonnām, dažas augošā secībā, bet citas dilstošā secībā. Kārtošanas primārās atslēgas kolonna ir norādīta vispirms.

Rakstzīmju konstante. Konstante, kas sastāv no burtiem, cipariem un “speciālajām” rakstzīmēm.

Pieprasīt: Kam ir stundas likme no 10 līdz 12 USD?

WHERE HRLY_RATE > = 10 UN HRLY_RATE< - 12

Rezultāts:

STRĀDĀTĀJA ID NAME HRLY_RATE SKILL_TYPE SUPV_ID

Šis vaicājums ilustrē dažus WHERE priekšraksta papildu līdzekļus: salīdzināšanas operatorus un Būla operatoru AND. Seši salīdzināšanas operatori (=,<>(nav vienāds),<, >, <=, >=). Būla operatorus AND, OR un NOT var izmantot, lai izveidotu saliktus nosacījumus vai noliegtu nosacījumu. Iekavas var izmantot, lai grupētu nosacījumus, kā tas ir ierasts programmēšanas valodās.

Salīdzināšanas operatori =,<>, <, >, <=, >=.

Būla operācijas UN (UN), VAI (VAI) un NE (VIŅŠ) .

Varat arī izmantot operatoru BETWEEN (starp), lai formulētu šo vaicājumu:

KUR HRLY_RATE NO 10. LĪDZ 12

BETWEEN var izmantot, lai salīdzinātu daudzumu ar diviem citiem lielumiem, no kuriem pirmais ir mazāks par otro, ja salīdzināmais daudzums var būt vienāds ar katru no šiem lielumiem vai jebkuru vērtību starp tām.

Pieprasījums: Uzrakstiet apmetējus, jumiķus un elektriķus.

WHERE SKILL_TYPE IN ("Apmetējs", "Jumiķis", "Elektriķis")

Rezultāts:

WORKER_ID NAME HRLY_RATE SKILL_TYPE SUPV_ID

1412 K.Nemo 13.75 Apmetējs 1520

2920 R. Garets 10.00 Jumiķis 2920

1520 G. Rikovers 11.75 Apmetējs 1520. g

Šis vaicājums izskaidro salīdzināšanas operatora IN (B) izmantošanu. Nosacījums WHERE tiek uzskatīts par patiesu, ja rindas specialitātes veids atrodas iekavās norādītajā komplektā, tas ir, ja specialitātes veids ir apmetējs, jumiķis vai elektriķis. Mēs atkal redzēsim IN operatoru apakšvaicājumos.

Pieņemsim, ka nevaram precīzi atcerēties savas specialitātes rakstību: “elektriķis” vai “elektronikas inženieris” vai kas cits. Aizstājējzīmes, kas aizstāj nedefinētas rakstzīmju virknes, atvieglo neprecīzu pareizrakstības atrašanu vaicājumā.

Rakstu simboli. Rakstzīmes, kas aizstāj nedefinētas rakstzīmju virknes.

Pieprasīt: Uzskaitiet darbiniekus, kuru specialitātes veids sākas ar “Elek”.

WHERE SKILL_TYPE LIKE ("Izvēlētie%")

Rezultāts:

DARBINIEKA ID NOSAUKUMS HRLY_RATE SKILL_TYPE SUPV_ID

1235 M. Faradejs 12.50 Elektriķis 1311

1311 H. Kolumbs 15.50 Elektriskais 1311

SQL ir divas aizstājējzīmes: % (procenti) un _ (pasvītrojums). Pasvītra aizstāj tieši vienu nedefinētu rakstzīmi. Procenti aizstāj patvaļīgu rakstzīmju skaitu, sākot ar nulli. Ja tiek izmantotas aizstājējzīmes, ir nepieciešams operators LIKE, lai salīdzinātu rakstzīmju mainīgos ar konstantēm. Citi piemēri:

NOSAUKUMS PATĪK "__Columbus"

NOSAUKUMS PATĪK "__K%"

Nosacījums pirmajā piemērā ir patiess, ja NAME sastāv no divām rakstzīmēm, kam seko “Columbus”. Tabulā WORKER visi nosaukumi sākas ar pirmo iniciāli un punktu. Tādējādi, izmantojot šo nosacījumu, mēs. Atradīsim visus darbiniekus ar uzvārdu "Kolumbs". Otrā piemēra nosacījums ļauj atrast visus darbiniekus, kuru uzvārdi sākas ar burtu “K”.

Pieprasīt: Atrodiet visus darbus, kas sākas nākamo divu nedēļu laikā.

KUR START_DATE NO CURRENT_DATE UN

Rezultāts:(Pieņemsim, ka pašreizējais datums ir PAŠREIZĒJAIS DATUMS = 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

Šis vaicājums ilustrē operatora BETWEEN izmantošanu ar datuma un intervāla vērtībām. CURRENT_DATE ir funkcija, kas vienmēr atgriež šodienas datumu. Izteiksme

CURRENT_DATE + INTERVAL "14" DAY

pašreizējam datumam pievieno divu nedēļu periodu. Tādējādi ASSIGNMENT tiek atlasīts (pieņemot, ka šodien ir 10.10.), ja tās START_DATE kolonnas vērtība ir no 10.10. līdz 24.10. No tā mēs redzam, ka datuma laukiem varam pievienot intervālu vērtības. Turklāt mēs varam reizināt intervālu vērtības ar veselu skaitļu vērtībām. Piemēram, pieņemsim, ka mēs vēlamies noskaidrot, kāds skaitlis būs pēc noteikta nedēļu skaita (apzīmē ar mainīgo NUM_WEEKS). Mēs to varam izdarīt šādi:

CURRENT_DATE + INTERVALS "7" DAY * NUM_WEEKS

2. Vairāku tabulu vaicājumi

Iespēja saistīt datu elementus pāri vienas tabulas robežām ir svarīga jebkurai datu bāzes valodai. Relāciju algebrā šo funkciju veic savienošanas darbība. Lai gan liela daļa SQL balstās tieši uz relāciju aprēķiniem, SQL savieno datus no dažādām tabulām līdzīgi kā relāciju algebras savienošanas operācijā. Tagad mēs parādīsim, kā tas tiek darīts. Apsveriet pieprasījumu:

Pieprasīt:

Atbildei nepieciešamie dati ir divās tabulās: STRĀDĀTĀJS un UZDEVUMS. SQL risinājumam komandā FROM ir jānorāda abas tabulas un jānorāda īpašs WHERE klauzulas veids:

ATLASĪT SKILL_TYPE

NO STRĀDNIEKA, UZDEVUMA

KUR DARBINIEKA.DARBINIEKA_ID = UZDEVUMI.DARBINIEKA_ID

UN BLDG_ID = 435

Kas šeit notiek? Mums jāapsver divi posmi, kā sistēma apstrādā šo pieprasījumu.

1. Kā parasti, vispirms tiek apstrādāta klauzula FROM. Tomēr šajā gadījumā, tā kā komanda norāda divas tabulas, sistēma izveido šo tabulu rindu Dekarta reizinājumu. Tas nozīmē, ka tiek izveidota (loģiski) viena liela tabula, kas sastāv no kolonnām no abām tabulām, katrai vienas tabulas rindai sapārojot ar katru otras tabulas rindu. Mūsu piemērā, tā kā tabulā WORKER ir piecas kolonnas un tabulā ASSIGNMENT ir četras kolonnas, Dekarta produktā, ko ģenerē komanda FROM, būs deviņas kolonnas. Dekarta reizinājuma kopējais rindu skaits ir vienāds ar m * n, kur m ir tabulas WORKER rindu skaits; un n ir rindu skaits tabulā ASSIGNMENT. Tā kā tabulā WORKER ir 7 rindas un tabulā ASSIGNMENT ir 19 rindas, Dekarta produktā būs 7x19 jeb 133 rindas. Ja komandā FROM ir uzskaitītas vairāk nekā divas tabulas, tiek izveidots visu komandā norādīto tabulu Dekarta reizinājums.

Dekarta produkts. Vienas tabulas katras rindas savienošanas rezultāts ar katrs rinda no citas tabulas.

2. Pēc milzu relāciju tabulas izveidošanas sistēma izmanto komandu WHERE tāpat kā iepriekš. Katra tabulas rinda, kas izveidota ar komandu FROM. tiek pārbaudīts, lai redzētu, vai nosacījums WHERE ir izpildīts. Rindas, kas neatbilst nosacījumam, tiek izslēgtas no izskatīšanas. SELECT klauzula tiek piemērota pārējām rindām.

WHERE klauzula mūsu vaicājumā satur divus nosacījumus:

1. STRĀDNIEKS. WORKER_ID = ASSIGNMENT.WORKER_ID

2. BLDG_ID = 435

Pirmais no šiem nosacījumiem ir savienojuma nosacījums. Ņemiet vērā: tā kā gan tabulās WORKER, gan ASSIGNMENT ir kolonna ar nosaukumu WORKER_ID, to Dekarta produktā būs divas kolonnas ar šādu nosaukumu. Lai tos atšķirtu, pirms kolonnas nosaukuma ievadām avota tabulas nosaukumu, atdalot to ar punktu.

Pirmais nosacījums nozīmē, ka jebkurā atlasītajā rindā kolonnas WORKER_ID vērtībai no tabulas WORKER ir jāatbilst kolonnas WORKER_ID vērtībai no tabulas ASSIGNMENT. Patiesībā mēs savienojam divas tabulas ar WORKER_ID. Visas rindas, kurās šo divu kolonnu vērtības nav vienādas, tiek izslēgtas no produktu tabulas. Tieši tas pats notiek, veicot relāciju algebras dabiskā savienojuma darbību. (Tomēr joprojām pastāv zināma atšķirība no dabiskā savienojuma: SQL automātiski nenoņem papildu kolonnu WORKER_ID). Pilnīgs šo divu tabulu savienojums ar papildu nosacījumu BLDG_ID = 435 ir parādīts attēlā. 1. Izmantojot komandu SELECT, tiks parādīts šāds vaicājuma rezultāts:

PRASMES VEIDS

Apmetējs

Jumiķis

Elektriķis

Rīsi. 1. DARBINIEKS un UZDEVUMA tabulu savienošana

Tagad mēs parādīsim, kā savienot tabulu ar sevi SQL.

Pieprasīt: Uzskaitiet darbiniekus, norādot viņu vadītāju vārdus.

ATLASĪT A.WORKER_NAME, B.WORKER_NAME

NO STRĀDNIEKA A, STRĀDĀTĀJA B

WHERE B.WORKER_ID = A.SUPV_ID

FROM klauzula šajā piemērā izveido divas tabulas WORKER "kopijas", piešķirot tām aizstājvārdus A un B. Pseidonīms ir tabulai piešķirts alternatīvs nosaukums. Pēc tam tabulas WORKER kopijas A un B savieno ar komandu WHERE, pamatojoties uz vienādības nosacījumu WORKER_ID B un SUPV_ID A. Tādējādi katra rinda no A tiek pievienota rindai B, kurā ir informācija par A rindas pārvaldnieku. (2. att.).

Rīsi. 2. Divu DARBINIEKA tabulas eksemplāru savienošana

Izvēloties divus darbinieku vārdus no katras rindas, mēs iegūstam nepieciešamo sarakstu:

A.NAMEB.NAME

M. Faradejs H. Kolumbs

K.Nemo G.Rickover R.Garrett R.Garrett

P. Meisons P. Meisons G. Rikovers G. Rikovers H. Kolumbs H. Kolumbs J. Barristers P. Meisons

Segvārds. Tabulai dots alternatīvs nosaukums.

A.WORKER_NAME pārstāv darbinieku un B.WORKER_NAME pārstāv vadītāju. Lūdzu, ņemiet vērā, ka daži darbinieki ir paši sev pārvaldnieki, kas izriet no vienādības WORKER_ID - SUPV_ID viņu rindās.

SQL varat vienlaikus saistīt vairāk nekā divas tabulas:

Pieprasīt

ATLASĪT WORKER_NAME

NO STRĀDĀTĀJA, UZDEVUMA, ĒKAS

KUR STRĀDĀTĀJA_ID = UZDEVUMS.STRĀDĀTĀJA_ID UN UZDEVUMS.BLDG_ID = ĒKA.BLDG_ID UN

TYPE = "birojs"

Rezultāts:

M. Faradejs

G.Rikovers

J.Barrister

Ņemiet vērā: ja kolonnas nosaukums (piemēram, WORKER_ID vai BLDG_ID) parādās vairāk nekā vienā tabulā, tad, lai izvairītos no neskaidrībām, kolonnas nosaukums ir jāpievieno sākotnējās tabulas nosaukumam. Bet, ja kolonnas nosaukums ir tikai vienā tabulā, piemēram, mūsu piemērā TYPE, tad nav neskaidrību, tāpēc tabulas nosaukums nav jānorāda.

SQL komandas šajā vaicājumā izveido vienu tabulu no trim relāciju datu bāzes tabulām. Pirmās divas tabulas tiek savienotas ar WORKER_ID, pēc tam trešo tabulu ar BLDG_ID pievieno iegūtajai tabulai. Stāvoklis

TYPE = "birojs"

WHERE klauzula liek izslēgt visas rindas, izņemot tās, kas paredzētas biroju ēkām. Tas atbilst pieprasījuma prasībām.

3. Apakšvaicājumi

Apakšvaicājums. Vaicājums vaicājumā

Apakšvaicājumu var ievietot vaicājuma WHERE klauzulā, tādējādi paplašinot WHERE klauzulas iespējas. Apskatīsim piemēru.

Pieprasīt: Kādas ir 435. ēkas strādnieku specialitātes?

ATLASĪT SKTLL_TYPE

NO WORKER WHERE WORKER_ID IN

(ATLASĪT WORKER_ID

KUR BLDG_ID = 435)

Apakšvaicājums šajā piemērā

(ATLASĪT WORKER_ID

KUR BLDG_ID = 435)

Tiek izsaukts vaicājums, kas satur apakšvaicājumu ārējs pieprasījums vai galvenais pieprasījums. Apakšvaicājuma rezultātā tiek izveidota šāda darbinieku ID kopa:

STRĀDĀTĀJA ID

Ārējais pieprasījums. Galvenais vaicājums, kas satur visus apakšvaicājumus.

Pēc tam šī ID kopa ārējā vaicājumā aizstāj apakšvaicājumu. No šī brīža ārējais vaicājums tiek izpildīts, izmantojot apakšvaicājuma izveidoto kopu. Ārējais vaicājums apstrādā katru tabulas WORKER rindu saskaņā ar WHERE klauzulu. Ja rindas WORKER_ID atrodas apakšvaicājuma izveidotajā (IN) kopā, tiek atlasīts rindas SKILL_TYPE un parādīts iegūtajā tabulā:

PRASMES VEIDS

Apmetējs

Jumiķis

Elektriķis

Ir ļoti svarīgi, lai apakšvaicājuma SELECT klauzula saturētu WORKER_ID un tikai WORKER_ID. Pretējā gadījumā ārējā vaicājuma WHERE klauzulai, kas nozīmē, ka WORKER_ID ir darbinieku ID kopā, nebūtu nozīmes.

Ņemiet vērā, ka apakšvaicājumu var loģiski izpildīt, pirms vismaz viena rinda tiek ņemta vērā galvenajā vaicājumā. Savā ziņā apakšvaicājums ir neatkarīgs no galvenā vaicājuma. To var izpildīt kā pilnu vaicājumu. Mēs sakām, ka šāds apakšvaicājums nav korelēts ar galveno vaicājumu. Kā mēs drīz redzēsim, apakšvaicājumi var būt saistīti.

Nekorelēts apakšvaicājums. Apakšvaicājums, kura vērtība ir neatkarīga no jebkura ārējā vaicājuma.

Šis ir apakšvaicājuma piemērs apakšvaicājumā.

Pieprasīt: uzskaitiet biroja ēkās norīkotos darbiniekus.

Atkal mēs aplūkojam vaicājumu, ar kuru mēs pārbaudījām savienojumu.

ATLASĪT WORKER_MAME

KUR IEEJAS WORKER_ID

(ATLASĪT WORKER_ID

WHERE BLDG_ID IN

KUR VEIDS = "birojs"))

Rezultāts:

M. Faradejs

G.Rikovers

J.Barrister

Ņemiet vērā, ka kolonnu nosaukumi nekur nav jāpievieno prefiksi ar tabulu nosaukumiem, jo ​​katrs apakšvaicājums apstrādā vienu un tikai vienu tabulu, tāpēc nevar rasties neskaidrības.

Vaicājuma izpilde notiek secībā no iekšpuses. Tas nozīmē, ka vispirms tiek izpildīts visdziļākais vaicājums (vai "apakšējais"), pēc tam tiek izpildīts apakšvaicājums, kas satur to, un pēc tam ārējais vaicājums.

Saistītie apakšvaicājumi. Visi iepriekš apspriestie apakšvaicājumi bija neatkarīgi no galvenajiem vaicājumiem, kuros tie tika izmantoti. Ar neatkarīgu mēs domājam, ka apakšvaicājumus var izpildīt atsevišķi kā pilnus vaicājumus. Tagad mēs pārejam pie apakšvaicājumu klases, kuru izpildes rezultāti var būt atkarīgi no galvenā vaicājuma aplūkotās rindas. Šādus apakšvaicājumus sauc par korelētiem apakšvaicājumiem.

Korelēts apakšvaicājums. Apakšvaicājums, kura rezultāts ir atkarīgs no galvenā vaicājumā aplūkotās rindas.

Pieprasīt: Uzskaitiet darbiniekus, kuru stundu likmes ir augstākas nekā viņu vadītājiem.

ATLASĪT WORKER_NAME

KUR A.HRLY_RATE >

(ATLASĪT B.HRLY_RATE

KUR B.DARBINIEKA_ID = A.SUPV_ID)

Rezultāts:

Loģiskās darbības šī pieprasījuma izpildei ir:

1. Sistēma izveido divas tabulas DARBINIEKS kopijas: kopiju A un kopiju B. Atbilstoši tam, kā mēs tās definējām, A attiecas uz darbinieku, B attiecas uz vadītāju.

2. Pēc tam sistēma ņem vērā katru A rindu. Dotā rinda tiek atlasīta, ja tā atbilst WHERE nosacījumam. Šis nosacījums nozīmē, ka rinda tiks atlasīta, ja tās HRLY_RATE vērtība ir lielāka par apakšvaicājuma ģenerēto HRLY_RATE.

3. Apakšvaicājums atlasa HRLY_RATE vērtību no rindas B, kuras WORKER_ID ir vienāds ar A rindas SUPV_ID. Šis brīdis izskatīts galvenajā pieprasījumā. Šī ir pārvaldnieka HRLY_RATE.

Ņemiet vērā: tā kā A.HRLY_RATE var salīdzināt tikai ar vienu vērtību, apakšvaicājumā ir jāatgriež tikai viena vērtība. Šī vērtība mainās atkarībā no tā, kura A rinda tiek ņemta vērā. Tādējādi apakšvaicājums ir korelēts ar galveno vaicājumu. Vairāk korelētu apakšvaicājumu piemēru redzēsim vēlāk, kad pētīsim iebūvētās funkcijas.

EXISTS un NOT EXISTS operatori

Pieņemsim, ka mēs vēlamies identificēt darbiniekus, kuri nav norīkoti strādāt noteiktā ēkā. Šķiet, ka šādu pieprasījumu var viegli izpildīt, vienkārši noliedzot pieprasījuma apstiprinošo versiju. Pieņemsim, piemēram, ka mūs interesē ēka ar BLDG_ID 435. Apsveriet pieprasījumu:

ATLASĪT WORKER_ID

KUR BLDG_ID NAV 435

Diemžēl tas ir nepareizs risinājuma formulējums. Pieprasījumā mums vienkārši tiks sniegti citās ēkās strādājošo darbinieku ID. Acīmredzot dažus no tiem var attiecināt arī uz 435. ēku.

Pareizi formulēts risinājums izmanto operatoru NOT EXISTS:

ATLASĪT WORKER_ID

KUR NAV

WHERE ASSIGNMENT.WORKER_ID = WORKER.WORKER_ID UN

Rezultāts:

WORKER_ID

Operatori EXISTS un NOT EXISTS vienmēr tiek novietoti pirms apakšvaicājuma. EXISTS tiek novērtēts kā patiess, ja apakšvaicājuma ģenerētā kopa nav tukša. Ja apakšvaicājuma ģenerētā kopa ir tukša, tad EXISTS iegūst vērtību “false”. Operators NOT EXISTS, protams, darbojas tieši pretēji. Tā ir patiesa, ja apakšvaicājuma rezultāts ir tukšs, un nepatiess, ja tā nav.

EXISTS operators. Atgriež patieso, ja rezultātu kopa nav tukša.

operators NOT EXISTS. Atgriež patieso, ja rezultātu kopa ir tukša.

Šajā piemērā mēs izmantojām operatoru NOT EXISTS. Apakšvaicājumā tiek atlasītas visas tabulas ASSIGNMENT rindas, kurās WORKER_ID ir tāda pati vērtība kā galvenajā vaicājumā aplūkotajai rindai, un BLDG_ID ir vienāds ar 435. Ja šī kopa ir tukša, tad galvenajā vaicājumā aplūkotā darbinieka rinda ir atlasīts, jo tas nozīmē, ka šis darbinieks nestrādā 435. ēkā.

Piedāvātajā risinājumā mēs izmantojām korelētu apakšvaicājumu. Ja mēs izmantojam operatoru IN, nevis NOT EXISTS, mēs varam iztikt ar nekorelētu apakšvaicājumu:

ATLASĪT WORKER_ID

KUR NAV IEKŠĒJĀS WORKER_ID

(ATLASĪT WORKER_ID

KUR BLDG_ID = 435)

Šis risinājums ir vienkāršāks nekā risinājums ar operatoru NOT EXISTS. Rodas dabisks jautājums: kāpēc mums ir vajadzīgi PASTĀVĒJI un NAV vispār? Atbilde ir tāda, ka NOT EXISTS ir vienīgais veids, kā atrisināt vaicājumus, kuru nosacījumā ir vārds "katrs". Šādi vaicājumi tiek atrisināti relāciju algebrā, izmantojot dalīšanas operāciju, un relāciju aprēķinā, izmantojot universālo kvantoru. Šeit ir piemērs vaicājumam ar vārdu “katrs” tā nosacījumā:

Pieprasīt: Uzskaitiet katrai ēkai norīkotos darbiniekus.

Šo jautājumu var realizēt SQL, izmantojot dubultās negācijas. Mēs pārformulēsim vaicājumu, lai iekļautu dubultu negatīvu:

Pieprasīt: Uzskaitiet tādus darbiniekus, kuriem Nav ir ēka, kurai tie nav piešķirti.

Mēs izcēlām dubulto negatīvo. Ir skaidrs, ka šis pieprasījums pēc loģikas ir līdzvērtīgs iepriekšējam.

Tagad mēs vēlamies formulēt risinājumu SQL. Lai gala risinājums būtu vieglāk saprotams, mēs vispirms sniedzam risinājumu provizoriskai problēmai: problēmai identificēt visas ēkas, kurām hipotētiskais strādnieks "1234" Nav iecelts.

(I) ATLASĪT BLDG_ID

KUR NAV

UZDEVUMS.DARBINIEKA_ID = 1234)

Mēs esam atzīmējuši šo vaicājumu (I), jo mēs uz to atsauksimies vēlāk. Ja nav nevienas ēkas, kas apmierina šo pieprasījumu, tad katrai ēkai tiek piešķirts strādnieks 1234, un tāpēc tas atbilst sākotnējā pieprasījuma nosacījumiem. Lai iegūtu sākotnējā vaicājuma risinājumu, mums ir jāvispārina vaicājums (I) no konkrēta darbinieka 1234 uz mainīgo WORKER_ID un jāpārvērš šis modificētais vaicājums par lielākā vaicājuma apakšvaicājumu. Lūk, risinājums:

(II) ATLASĪT DARBINIEKA_ID

KUR NAV

KUR NAV

WHERE ASSIGNMENT.BLDG_ID = ĒKA.BLDG_ID UN

ASSIGNMENT.WORKER_ID = STRĀDĀTĀJA.DARBINIEKA_ID)

Rezultāts:

STRĀDĀTĀJA ID

Ņemiet vērā, ka apakšvaicājums, kas sākas ar vaicājuma ceturto rindiņu (II), ir identisks vaicājumam (I), un "1234" ir aizstāts ar WORKER.WORKER_ID. Vaicājumu (II) var lasīt šādi:

Atlasiet WORKER_ID no WORKER, ja nav nevienas ēkas, kurai WORKER_ID nav piešķirts.

Tas atbilst sākotnējā pieprasījuma nosacījumiem.

Mēs redzam, ka operatoru NOT EXISTS var izmantot, lai formulētu tos vaicājumus, kuriem bija nepieciešama dalīšanas darbība relāciju algebrā un universāls kvantors relāciju aprēķinā. No lietošanas vienkāršības viedokļa operators NOT EXISTS nesniedz īpašu labumu, kas nozīmē, ka SQL vaicājumi, kas izmanto NOT EXISTS divas reizes, nav vieglāk saprotami nekā relāciju algebras risinājumi ar dalīšanu vai relāciju aprēķinu risinājumi ar universālajiem kvantoriem. Būs nepieciešams vairāk pētījumu, lai izveidotu valodas konstrukcijas, kas ļautu šādus vaicājumus atrisināt dabiskāk.

Iebūvētās funkcijas

Apskatīsim šāda veida jautājumus:

Kādas ir maksimālās un minimālās stundas likmes? Kāds ir vidējais dienu skaits, ko darbinieki strādā ēkā 435? Cik kopējais dienu skaits ir atvēlēts 312. korpusa apmetuma darbiem? Cik daudz dažādu specialitāšu ir?

Lai atbildētu uz šiem jautājumiem, ir nepieciešamas statistikas funkcijas, kas aplūko daudzas tabulas rindas un atgriež vienu vērtību. SQL ir piecas šādas funkcijas, ko sauc par iebūvētajām funkcijām vai iestatītajām funkcijām. Šīs funkcijas ir SUM (summa), AVG (vidējais), COUNT (daudzums), MAX (maksimums) un MIN (minimums).

Iebūvēta funkcija (iestatīta funkcija). Statistikas funkcija, kas darbojas vairākās rindās: SUM (summa), AVG (vidējais), COUNT (daudzums), MAX (maksimums), MIN (minimums).

Pieprasīt: Kādas ir maksimālās un minimālās stundas likmes?

ATLASĪT MAX(HRLY_RATE), MIN(HRLY_RATE)

Rezultāts: 17.40, 8.20

MAX funkcijas un MIN darbojas vienā tabulas kolonnā. Viņi no šīs kolonnas izvēlas attiecīgi maksimālo vai minimālo vērtību. Mūsu vaicājuma formulējums nesatur WHERE klauzulu. Lielākajai daļai vaicājumu tas var nebūt tā, kā parādīts mūsu nākamajā piemērā.

Pieprasīt: Kāds ir vidējais dienu skaits, ko darbinieki strādā ēkā 435?

ATLASĪT AVG(NUM_DAYS)

KUR BLDG_ID =435

Rezultāts: 12.33

Pieprasīt: Cik kopējais dienu skaits ir atvēlēts 312. korpusa apmetuma darbiem?

ATLASĪT SUMMU (NUM_DAYS)

NO NODARBINĀJUMA, STRĀDNIEKS

KUR STRĀDĀTĀJA_ID = UZDEVUMS.STRĀDĀTĀJA_ID UN

SKILL_TYPE = "Apmetējs" UN

Rezultāts: 27

Risinājums izmanto savienojumu starp tabulām ASSIGNMENT un WORKER. Tas ir nepieciešams, jo SKILL_TYPE ir tabulā WORKER un BLDG_ID ir tabulā ASSIGNMENT.

Pieprasīt: Cik daudz dažādu specialitāšu ir?

ATLASĪT COUNT (DISTINCT SKILL_TYPE)

Rezultāts: 4

Tā kā viena un tā pati specialitāte var parādīties vairākās dažādās rindās, šajā vaicājumā ir jāizmanto DISTINCT atslēgvārds, lai sistēma neuzskaitītu vienu un to pašu specialitātes veidu vairāk nekā vienu reizi. DISTINCT operatoru var izmantot ar jebkuru no iebūvētajām funkcijām, lai gan, protams, tas ir lieks ar MAX un MIN funkcijām.

ATŠĶIRĪGI. Operators, kas novērš dublētās rindas.

Funkcijas SUM un AVG jāizmanto tikai ar ciparu kolonnām. Citas funkcijas var izmantot gan ar ciparu, gan rakstzīmju datiem. Ar aprēķinātajām izteiksmēm var izmantot visas funkcijas, izņemot COUNT. Piemēram:

Pieprasīt: Kāda ir vidējā nedēļas alga?

ATLASĪT AVG (40 * HRLY_RATE)

Rezultāts: 509.14

COUNT var attiekties uz visu rindu, nevis uz atsevišķu kolonnu :

Pieprasīt: Cik ēkām ir 3. kvalitātes līmenis?

ATLASĪT SKAITS (*)

NO ĒKAS, KUR

Rezultāts: 3

Kā liecina visi šie piemēri, ja komanda SELECT satur iebūvētu funkciju, nekas cits šajā SELECT komandā nevar parādīties. Vienīgais izņēmums no šī noteikuma ir klauzula GROUP BY, kuru mēs tagad apskatīsim.

GROUP BY un HAVING klauzulas

Pārvaldībā bieži ir nepieciešama statistiskā informācija par katru grupu daudzās grupās. Piemēram, apsveriet šādu vaicājumu:

Pieprasīt: Katram vadītājam noskaidrojiet maksimālo stundas tarifa likmi starp viņa padotajiem.

Lai atrisinātu šo problēmu, mums ir jāsadala darbinieki grupās atbilstoši viņu vadītājiem. Pēc tam mēs noteiksim maksimālo cenu katrā grupā. SQL tas tiek darīts šādi:

GROUP PĒC SUPV_ID

Rezultāts:

SUPV_IDMAX(HRLY RATE)

Apstrādājot šo vaicājumu, sistēma vispirms sadala tabulas WORKER rindas grupās, izmantojot šādu noteikumu. Rindas tiek ievietotas vienā grupā tad un tikai tad, ja tām ir vienāds SUPV_ID. Pēc tam katrai grupai tiek piemērota klauzula SELECT. Tā kā šajā grupā ir tikai viena SUPV_ID vērtība, grupā nav SUPV_ID nenoteiktības. Katrai grupai klauzula SELECT izvada SUPV_ID, kā arī aprēķina un izvada MAX(HRLY_RATE) vērtību. Rezultāts ir parādīts iepriekš.

Komandā SELECT ar iebūvētām funkcijām var parādīties tikai tās kolonnas, kas ir iekļautas klauzulā GROUP BY. Ņemiet vērā, ka SUPV_ID var izmantot komandā SELECT, jo tas ir iekļauts klauzulā GROUP BY.

GROUP BY klauzula. Norāda, ka rindas ir jāsadala grupās ar norādītās kolonnas(-u) kopīgām vērtībām.

GROUP BY klauzula ļauj veikt noteiktus sarežģītus aprēķinus. Piemēram, mēs varētu vēlēties noskaidrot šo maksimālo cenu vidējo vērtību. Tomēr aprēķins ar iebūvētām funkcijām ir ierobežots tādā nozīmē, ka tas neļauj izmantot iebūvētās funkcijas citās iebūvētajās funkcijās. Tātad tāds izteiciens kā

AVG(MAX(HRLY_RATE))

aizliegts. Šāda pieprasījuma īstenošana sastāvēs no diviem posmiem. Vispirms jaunā tabulā jāievieto maksimālās cenas, bet otrajā solī jāaprēķina to vidējās cenas.

Varat izmantot klauzulu WHERE ar komandu GROUP BY:

Pieprasīt: Par katru ēkas veidu uzziniet vidējais līmenis kvalitāte starp 1. statusa ēkām.

ATLASĪT VEIDU, AVG (QLTY_LEVEL)

KUR STATUSS = 1

Rezultāts:

TYPEAVG (QLTY_LEVEL)

Veikals 1

Dzīvojamā ēka 3

WHERE klauzula tiek izpildīta pirms GROUP BY priekšraksta. Tādējādi neviena grupa nevar saturēt rindu, kuras statuss nav 1. Statusa 1 rindas tiek grupētas pēc vērtības TYPE, un pēc tam katrai grupai tiek piemērota klauzula SELECT.

IR frāze. Novieto nosacījumus grupām.

Mēs varam arī piemērot nosacījumus grupām, kas izveidotas ar GROUP BY klauzulu. Tas tiek darīts, izmantojot frāzi HAVING. Pieņemsim, piemēram, ka mēs nolēmām precizēt vienu no iepriekšējiem vaicājumiem:

Pieprasīt: Katram vadītājam, kuram ir vairāk nekā viens padotais, noskaidro maksimālo stundas tarifa likmi starp viņa padotajiem.

Mēs varam atspoguļot šo nosacījumu ar atbilstošu komandu HAVING:

ATLASĪT SUPV_ID, MAX (HRLY_RATE)

NO DARBINIEKU GRUPAS, PĒC SUPV_ID

AR SKAITĪBU(*) > 1

Rezultāts:

SUPV_ID MAX (HRLY_RATE)

Atšķirība starp WHERE un HAVING klauzulas ir tāda, ka WHERE attiecas uz rindām, bet HAVING attiecas uz grupām.

Vaicājumā var būt gan WHERE, gan HAVING klauzula. Šajā gadījumā WHERE klauzula tiek izpildīta vispirms, jo tā tiek izpildīta pirms grupēšanas. Piemēram, apsveriet šādu iepriekšējā vaicājuma modifikāciju:

Pieprasīt: Katram ēkas tipam noskaidro vidējo kvalitātes līmeni starp 1. statusa ēkām. Aplūko tikai tos ēku tipus, kuru maksimālais kvalitātes līmenis nepārsniedz 3.

ATLASĪT VEIDU, AVG (QLTY_JLEVEL)

KUR STATUSS = 1

AR MAX (QLTY_LEVEL)<= 3

Rezultāts:

AVG VEIDS (QLTY_LEVEL)

Veikals 1

Dzīvojamā ēka 3

Ņemiet vērā, ka, sākot ar klauzulu FROM, klauzulas tiek izpildītas secībā, un pēc tam tiek piemērota klauzula SELECT. Tādējādi tabulai BUILDING tiek piemērota klauzula WHERE un tiek dzēstas visas rindas, kurās STATUSS atšķiras no 1. Atlikušās rindas ir sagrupētas pēc TYPE; visas rindas ar vienu un to pašu TYPE vērtību nonāk vienā grupā. Tādējādi tiek izveidotas vairākas grupas, viena katrai TYPE vērtībai. Pēc tam katrai grupai tiek piemērota klauzula HAVING, un tās grupas, kuru maksimālā kvalitātes līmeņa vērtība pārsniedz 3, tiek noņemtas. Visbeidzot, SELECT klauzula tiek piemērota pārējām grupām.

7. Iebūvētās funkcijas un apakšvaicājumi

Iebūvētās funkcijas var izmantot tikai klauzulā SELECT vai komandā HAVING. Tomēr SELECT klauzula, kas satur iekļautu funkciju, var būt daļa no apakšvaicājuma. Apskatīsim šāda apakšvaicājuma piemēru:

Pieprasīt: Kuriem darbiniekiem ir augstāka par vidējo stundas tarifa tarifu?

ATLASĪT WORKER_NAME

KUR HRLY_RATE >

(ATLASĪT AVG(HRLY_RATE)

Rezultāts:

H. Kolumbs

Ņemiet vērā, ka apakšvaicājums nav korelēts ar galveno vaicājumu. Apakšvaicājums atgriež tieši vienu vērtību - vidējo stundas likmi. Galvenais vaicājums atlasa strādnieku tikai tad, ja viņa likme ir lielāka par aprēķināto vidējo.

Korelētajos vaicājumos var izmantot arī iebūvētās funkcijas:

Jautājums: Kuram darbiniekam viena un tā paša vadītāja padotajiem ir augstāka stundas tarifa likme par vidējo stundas tarifa likmi?

Šajā gadījumā tā vietā, lai aprēķinātu vienu vidējo stundas tarifa likmi visiem darbiniekiem, mums ir jāaprēķina vidējā likme katrai darbinieku grupai, kas atskaitās vienam un tam pašam vadītājam. Turklāt mūsu aprēķins ir jāveic no jauna katram galvenajā vaicājumā apskatītajam darbiniekam:

IZVĒLIES A. WORKER_NAME

SQL ļauj ligzdot vaicājumus savā starpā. Parasti apakšvaicājums atgriež vienu vērtību, kas tiek pārbaudīta, lai noskaidrotu, vai predikāts ir patiess.

Meklēšanas vienumu veidi:
. Salīdzinājums ar apakšvaicājuma rezultātu (=, >=)
. Pārbauda piederību apakšvaicājuma (IN) rezultātiem
. Esamības pārbaude (EXISTS)
. Vairāki (kvantitatīvi) salīdzinājumi (JEBKURŠ, VISI)

Piezīmes par ligzdotiem vaicājumiem:
. Apakšvaicājumā ir jāatlasa tikai viena kolonna (izņemot apakšvaicājumu ar predikātu EXISTS), un tā rezultāta datu tipam jāatbilst predikātā norādītās vērtības datu tipam.
. Dažos gadījumos varat izmantot DISTINCT atslēgvārdu, lai nodrošinātu, ka tiek atgriezta viena vērtība.
. Apakšvaicājumā nevar iekļaut klauzulu ORDER BY vai UNION.
. Apakšvaicājums var atrasties pa kreisi vai pa labi no meklēšanas nosacījuma.
. Apakšvaicājumos var izmantot apkopošanas funkcijas bez GROUP BY klauzulas, kas automātiski atgriež īpašu vērtību jebkuram rindu skaitam, īpašu IN predikātu un kolonnu izteiksmēm.
. Kad vien iespējams, apakšvaicājumu vietā izmantojiet tabulas JOIN savienojumus.

Ligzdoto vaicājumu piemēri:

SELECT * FROM Pasūtījumi WHERE SNum=(SELECT SNum FROM SalesPeople WHERE SName=’Motika’)
SELECT * FROM Pasūtījumi WHERE SNum IN (SELECT SNum FROM SalesPeople WHERE City=’London’)
SELECT * FROM Pasūtījumi WHERE SNum=(SELECT DISTINCT SNum FROM Orders WHERE CNum=2001)
SELECT * FROM Pasūtījumi WHERE Amt> (SELECT AVG(Amt) FROM Orders WHERE Odate=10/04/1990)
SELECT * FROM Customer WHERE CNum=(SELECT SNum+1000 FROM SalesPeople WHERE SName=’Serres’)

2) Saistītie apakšvaicājumi

SQL varat izveidot apakšvaicājumus, kas atsaucas uz tabulu no ārējā vaicājuma. Šajā gadījumā apakšvaicājums tiek izpildīts vairākas reizes, vienu reizi katrai tabulas rindai no ārējā vaicājuma. Tāpēc ir svarīgi, lai apakšvaicājumā tiktu izmantots indekss. Apakšvaicājums var piekļūt tai pašai tabulai kā ārējai. Ja ārējais vaicājums atgriež salīdzinoši nelielu rindu skaitu, saistītais apakšvaicājums būs ātrāks nekā nesaistītais. Ja apakšvaicājums atgriež nelielu skaitu rindu, saistītais vaicājums būs lēnāks nekā nesaistītais vaicājums.

Saistīto apakšvaicājumu piemēri:

SELECT * FROM SalesPeople Galvenā WHERE 1(SELECT AVG(Amt) FROM Orders O2 WHERE O2.CNum=O1.CNum) //atgriež visus pasūtījumus, kuru vērtība pārsniedz konkrētā klienta vidējo pasūtījuma vērtību

3) Predikāts PASTĀV

Sintaktiskā forma: PASTĀV ()

Predikāts izmanto apakšvaicājumu kā argumentu un novērtē kā patiesu, ja apakšvaicājumā ir izvade, un false citādi. Apakšvaicājums tiek izpildīts vienreiz un var saturēt vairākas kolonnas, jo to vērtības netiek pārbaudītas, bet rindu klātbūtnes rezultāts tiek vienkārši reģistrēts.

Piezīmes par predikātu EXISTS:
. EXISTS ir predikāts, kas atgriež TRUE vai FALSE, un to var izmantot atsevišķi vai kopā ar citām Būla izteiksmēm.
. EXISTS savā apakšvaicājumā nevar izmantot apkopošanas funkcijas.
. Korelētajos apakšvaicājumos predikāts EXISTS tiek izpildīts katrai ārējās tabulas rindai.
. Predikātu EXISTS var apvienot ar tabulu savienojumiem.

Predikāta EXISTS piemēri:

SELECT * FROM Customer WHERE EXISTS (SELECT * FROM Customer WHERE City=’Sanhosē’) — atgriež visus klientus, ja kāds no viņiem dzīvo Sanhosē.
SELECT DISTINCT SNum FROM Customer First WHERE NOT EXISTS (SELECT * FROM Customer Send WHERE Send.SNum=First.SNum AND Send.CNumFirst.CNum) — atgriež to pārdevēju skaitu, kuri apkalpojuši tikai vienu klientu.
SELECT DISTINCT F.SNum, SNum, F. City FROM SalesPeople F, Customer S WHERE EXISTS (SELECT * FROM Customer T WHERE S.SNum=T.SNum AND S.CNumT.CNum UN F.SNum=S.SNum) — atgriež visu pārdevēju, kuri apkalpoja vairākus klientus, numuri, vārdi un dzīvesvietas pilsētas.
SELECT * FROM SalesPeople Frst WHERE EXISTS (SELECT * FROM Klients Sūtīt WHERE Frst.SNum=Send.SNum UN 1

4) Kvantitatīvās salīdzināšanas predikāti

Sintaktiskā forma: (=|>|=|) JEBKĀRĀ|VISI ()

Šie predikāti kā argumentu izmanto apakšvaicājumu, tomēr, salīdzinot ar predikātu EXISTS, tie tiek lietoti kopā ar relāciju predikātiem (=,>=). Šajā ziņā tie ir līdzīgi IN predikātam, bet tiek izmantoti tikai ar apakšvaicājumiem. Standarts ļauj izmantot DAŽU atslēgvārdu, nevis JEBKURU, taču ne visas DBVS to atbalsta.

Piezīmes par salīdzināšanas predikātiem:
. Predikāts ALL tiek novērtēts kā TRUE, ja katra apakšvaicājuma izpildes laikā atlasītā vērtība atbilst nosacījumam, kas norādīts ārējā vaicājuma predikātā. Visbiežāk to izmanto ar nevienlīdzību.
. Predikāts ANY tiek novērtēts kā TRUE, ja vismaz viena apakšvaicājuma izpildes laikā atlasītā vērtība atbilst nosacījumam, kas norādīts ārējā vaicājuma predikātā. Visbiežāk to izmanto ar nevienlīdzību.
. Ja apakšvaicājums neatgriež nevienu rindu, tad VISI automātiski iegūst vērtību TRUE (tiek uzskatīts, ka salīdzināšanas nosacījums ir izpildīts), bet JEBKURAM tā iegūst vērtību FALSE.
. Ja salīdzinājums ir TRUE nevienai rindai un ir viena vai vairākas rindas ar NULL vērtību, tad ANY atgriež NEZINĀMS.
. Ja salīdzinājums ir FALSE nevienai rindai un ir viena vai vairākas rindas ar NULL vērtību, ALL atgriež NEZINĀMS.

Kvantitatīvā salīdzinājuma predikāta piemēri:

SELECT * FROM SalesPeople WHERE Pilsēta = ANY (IZVĒLIES Pilsētu NO klienta)
SELECT * FROM Pasūtījumi WHERE Amt ALL (SELECT Rating FROM Customer WHERE City='Rome')

5) Unikalitātes predikāts

UNIKĀLS|ATŠĶIRĪGS ()

Predikāts tiek izmantots, lai pārbaudītu apakšvaicājuma izejas datu unikalitāti (dublikātu neesamību). Turklāt UNIQUT predikātā virknes ar NULL vērtībām tiek uzskatītas par unikālām, un predikātā DISTINCT divas nenoteiktas vērtības tiek uzskatītas par vienādām viena ar otru.

6) Atbilstības predikāts

MATCH ()

Predikāts MATCH pārbauda, ​​vai vaicājuma virknes vērtība atbilst jebkuras apakšvaicājuma virknes vērtībai. Šis apakšvaicājums atšķiras no IN AND ANY predikātiem ar to, ka tas ļauj apstrādāt “daļējas” (PARTIAL) atbilstības, kas var rasties rindās, kurām ir dažas NULL vērtības.

7) Vaicājumi sadaļā NO

Faktiski ir likumīgi izmantot apakšvaicājumu visur, kur ir atļauta tabulas atsauce.

SELECT Cname, Tot_Amt FROM Customer, (SELECT CNum, SUM(Amt) AS Tot_Amt FROM Orders GROUP BY CNum) WHERE City='London' AND Customer.CNum=Orders.CNum
//subquery atgriež katra klienta no Londonas veikto pasūtījumu kopējo summu.

8) Rekursīvie vaicājumi

AR REKURSĪVU
Q1 KĀ IZVĒLĒTIES … NO … KUR …
Q2 KĀ IZVĒLĒTIES … NO … KUR …




Tops