Folosind funcții de agregare imbricate. Utilizarea funcțiilor agregate și a interogărilor imbricate într-o instrucțiune select. Utilizarea funcțiilor agregate

valoarea coloanei Scor. Tabelul 5.7. Funcții agregate
Funcţie Rezultat
CONTA Numărul de rânduri sau valorile câmpului neblank pe care le-a selectat interogarea
SUMĂ Suma tuturor valorilor selectate pentru acest câmp
AVG Media aritmetică a tuturor valorilor selectate pentru acest câmp
MIN Cea mai mică dintre toate valorile selectate pentru acest câmp
MAX Cea mai mare dintre toate valorile selectate pentru acest câmp
R1
Numele complet Disciplina Nota
Grupa 1 Petrov F.I. Baze de date 5
Sidorov K. A. Baze de date 4
Mironov A.V. Baze de date 2
Stepanova K. E. Baze de date 2
Krylova T. S. Baze de date 5
Vladimirov V. A. Baze de date 5
Grupa 2 Sidorov K. A. Teoria informației 4
Stepanova K. E. Teoria informației 2
Krylova T. S. Teoria informației 5
Mironov A.V. Teoria informației Nul
Grupa 3 Trofimov P. A. Rețele și telecomunicații 4
Ivanova E. A. Rețele și telecomunicații 5
Utkina N.V. Rețele și telecomunicații 5
Grupa 4 Vladimirov V. A. Limba engleză 4
Trofimov P. A. Limba engleză 5
Ivanova E. A. Limba engleză 3
Petrov F.I. Limba engleză 5

Funcții agregate sunt folosite similar numelor de câmp într-o instrucțiune SELECT, dar cu o singură excepție: iau numele câmpului ca argument. Numai câmpurile numerice pot fi utilizate cu funcțiile SUM și AVG. Atât câmpurile numerice, cât și cele de caractere pot fi utilizate cu funcțiile COUNT , MAX și MIN. Când sunt utilizate cu câmpuri de caractere, MAX și MIN le vor traduce în codul ASCII echivalent și le vor procesa în ordine alfabetică. Unele SGBD-uri permit utilizarea agregatelor imbricate, dar aceasta este o abatere de la standardul ANSI cu toate consecințele care decurg.

De exemplu, puteți calcula numărul de studenți care au susținut examene la fiecare disciplină. Pentru a face acest lucru, trebuie să rulați o interogare grupată după câmpul „Disciplina” și să afișați ca rezultat numele disciplinei și numărul de rânduri din grup pentru această disciplină. Folosirea caracterului * ca argument pentru funcția COUNT înseamnă numărarea tuturor rândurilor din grup.

SELECTAȚI R1.Discipline, COUNT(*) FROM R1 GROUP BY R1.Discipline

Rezultat:

Dacă vrem să numărăm numărul de persoane care au promovat examenul la orice disciplină, atunci trebuie să excludem valorile incerte din raportul inițial înainte de grupare. În acest caz, cererea va arăta astfel:

Obtinem rezultatul:

În acest caz, linia cu studentul

Mironov A.V. Teoria informației Nul

nu se va încadra în setul de tupluri înainte de grupare, deci numărul de tupluri din grup de disciplinat " Teoria informației„va fi cu 1 mai puțin.

Poate fi folosit funcții agregate de asemenea, fără operația de pregrupare, caz în care întreaga relație este considerată ca un grup și pentru acest grup se poate calcula o valoare per grup.

Revenind din nou la baza de date „Sesiune” (tabelele R1, R2, R3), aflăm numărul de examene promovate cu succes:

Acest lucru este, desigur, diferit de selectarea unui câmp, deoarece o singură valoare este întotdeauna returnată, indiferent de câte rânduri sunt în tabel. Argument funcții agregate pot exista coloane separate de tabel. Dar pentru a calcula, de exemplu, numărul de valori distincte ale unei anumite coloane dintr-un grup, trebuie să utilizați cuvântul cheie DISTINCT împreună cu numele coloanei. Să calculăm numărul de note diferite primite la fiecare disciplină:

Rezultat:

Rezultatul poate include valoarea câmpului de grupare și mai multe funcții agregate, iar în condiții de grupare puteți utiliza mai multe câmpuri. În acest caz, grupurile sunt formate conform unui set de câmpuri de grupare specificate. Operațiile cu funcții de agregare pot fi aplicate pentru a uni mai multe tabele sursă. De exemplu, să punem întrebarea: stabiliți pentru fiecare grupă și fiecare disciplină numărul de studenți care au promovat cu succes examenul și punctajul mediu la disciplină.

Rezultat:

Nu putem folosi funcții agregateîn clauza WHERE deoarece predicatele sunt evaluate în termenii unei singure linii și funcții agregate- în ceea ce priveşte grupurile de linii.

Clauza GROUP BY vă permite să definiți un subset de valori dintr-un anumit câmp în termenii unui alt câmp și să aplicați o funcție de agregare subsetului. Acest lucru face posibilă combinarea câmpurilor și funcții agregateîntr-o singură clauză SELECT. Funcții agregate poate fi folosit atât în ​​expresia pentru ieșirea rezultatelor liniei SELECT, cât și în expresia pentru condiția de procesare a grupurilor HAVING generate. În acest caz, fiecare funcție agregată este calculată pentru fiecare grup selectat. Valori obținute din calcul funcții agregate, poate fi folosit pentru a afișa rezultatele corespunzătoare sau pentru a condiționa selecția grupurilor.

Să construim o interogare care să afișeze grupuri în care s-a primit mai mult de o notă negativă la o disciplină la examene:

Pe viitor, de exemplu, nu vom lucra cu baza de date „Sesiune”, ci cu baza de date „Bancă”, constând dintr-un tabel F, care stochează relația F care conține informații despre conturile din sucursalele unei anumite bănci:

F = (N, Nume complet, Sucursală, Data deschiderii, Data închiderii, Sold); Q = (Sucursală, Oraș);

întrucât pe această bază se poate ilustra mai clar lucrarea cu funcţii agregate şi grupare.

De exemplu, să presupunem că vrem să găsim soldul total al conturilor bancare. Puteți face o interogare separată pentru fiecare dintre ele selectând SUM(Sold) din tabelul pentru fiecare ramură. GROUP BY vă va permite totuși să le puneți pe toate într-o singură comandă:

SELECTARE Branch, SUM(Remaining) FROM F GROUP BY Branch;

Se aplică GROUP BY funcții agregate independent pentru fiecare grup definit folosind valoarea câmpului Branch. Grupul este format din rânduri cu aceeași valoare a câmpului Branch și

Introducere

SQL (Structured Query Language) - Limbajul de interogare structurat - limbaj standard de interogare pentru lucrul cu baze de date relaționale.

Primul standard internațional pentru limbajul SQL a fost adoptat în 1989 (în continuare îl vom numi SQL/89 sau SQL1). Uneori, standardul SQL1 este numit și standardul ANSI/ISO și marea majoritate a SGBD-uri disponibile pe piață acceptă pe deplin acest standard.

La sfârșitul anului 1992, a fost adoptat un nou standard internațional pentru limbajul SQL (care de acum înainte se va numi SQL/92 sau SQL2). Și nu este lipsit de dezavantajele sale, dar în același timp este semnificativ mai precis și complet decât SQL/89. În prezent, majoritatea producătorilor de SGBD fac modificări produselor lor, astfel încât acestea să fie mai conforme cu standardul SQL2.

Ultimul standard pentru limbajul SQL a fost lansat în 1996. Se numește SQL3.

SQL nu poate fi clasificat pe deplin ca un limbaj de programare tradițional: nu conține operatori tradiționali de control al fluxului de programe, operatori de declarare a tipului și multe altele, conține doar un set de operatori de acces standard la datele stocate în baza de date; Instrucțiunile SQL sunt încorporate în limbajul de programare de bază, care poate fi orice limbaj standard, cum ar fi C++, PL, COBOL etc. În plus, instrucțiunile SQL pot fi executate direct interactiv.

1. Structura SQL.

SQL conține următoarele secțiuni:

1. Operatori DDL (Data Definition Language).

Operator Sens Acţiune
CREAȚI TABEL Creați un tabel Creează un tabel nou în baza de date
DROP TABLE Șterge tabelul Îndepărtează un tabel din baza de date
ALTER TABLE Editați tabelul Modifică structura unui tabel existent
CREATE VIEW Creați vizualizare Creează o masă virtuală, de ex. un tabel care nu există de fapt, dar este modelat folosind acest operator.
ALTER VIEW Schimbați vizualizarea Modifică structura sau conținutul unui tabel virtual
DROP VIEW Șterge vizualizarea Șterge descrierea tabelului virtual. Nu este nevoie să ștergeți tabelul în sine, deoarece... de fapt nu există.
CREAȚI INDEX Creați index Creează o structură fizică specială numită index care oferă acces mai rapid la date
INDICE DE CĂDERARE Eliminați indexul Șterge structura creată
CREAȚI SINONIM Creați sinonim
SINONIM PĂDUT Eliminați sinonimul

2. Limbajul de manipulare a datelor (DML) Operatori de manipulare a datelor



3. Limbajul de interogare a datelor (DQL)

4. Instrumente de control al tranzacțiilor (DCL)

5. Instrumente de administrare a datelor (DDL)

SQL programatic

2. Tipuri de date

Următoarele tipuri de date sunt acceptate în SQL/89: CHARACTER, NUMERIC, DECIMAL, INTEGER, SMALLINT, FLOAT, REAL, DOUBLE PRECISION. Aceste tipuri de date sunt clasificate în șir de caractere, număr exact și numere aproximative.

Standardul SQL92 adaugă următoarele tipuri de date:

VARCHAR(n) - șiruri de caractere cu lungime variabilă

NCHAR(N) – șiruri de caractere localizate de lungime constantă

NCHAR VARYING(n) - șiruri de caractere localizate de lungime variabilă

BIT(n) - șir de biți de lungime constantă

BIT VARYING(n) - șir de biți de lungime variabilă

DATE data calendaristică

TIMESTAMP (precizie) data și ora

Interval de timp INTERVAL

3. instrucțiunea SELECT

Select este singurul operator de căutare care înlocuiește toate operațiile de algebră relațională.

Diagrama de sintaxă a instrucțiunii SELECT este prezentată în Fig. 1


Aici cuvântul cheie ALL înseamnă că setul rezultat de rânduri include toate rândurile care îndeplinesc condițiile de interogare. Cuvântul cheie DISTINCT înseamnă că numai rânduri distincte sunt incluse în setul de rezultate, adică. rândurile de rezultate duplicat nu sunt incluse în set. Dacă nu este prezent niciun cuvânt cheie, atunci această situație este interpretată ca prezența cuvântului cheie ALL.

Caracterul * înseamnă că setul de rezultate include toate coloanele din tabelele sursă ale interogării.

Partea FROM specifică o listă de relații sursă (tabele) ale interogării.

În partea UNDE sunt specificate condițiile de selectare a termenului rezultatului sau condițiile de unire a tuplurilor din tabelele sursă.

Partea GROUP BY specifică o listă de câmpuri de grupare.

Partea HAVING specifică condițiile predicate impuse fiecărui grup.

Partea ORDER BY specifică o listă de câmpuri pentru ordonarea rezultatului.

Următoarele predicate pot fi folosite în exprimarea condițiilor pentru partea WHERE:

· predicat de comparație cu model LIKE și NOT LIKE

· predicatul EXISTĂ și NU EXISTĂ.

predicate de comparație { =, <>, >,<,>=,<=,}. Diagrama sintactică a predicatelor de comparație este prezentată în Fig. 2


predicat IN - inclus in multime / neinclus in multime.

Predicatul IN sau NOT IN poate fi folosit și pentru a compara expresia testată cu o subinterogare, în acest caz, diagrama de sintaxă este prezentată în Fig. 5.

Predicatul IN este adevărat atunci când valoarea atributului specificat în expresia testată pentru tuplu curent se potrivește cu cel puțin una din setul de valori obținute ca urmare a executării subinterogării corespunzătoare sau conținute în lista de valori. Dimpotrivă, predicatul NOT IN este adevărat numai dacă valoarea atributului specificat în tuplu curent nu se potrivește cu niciunul dintre setul de valori definit de o subinterogare inline sau de o listă de valori dată.


predicat LIKE - include (similar)

Modelul poate conține _ litere de subliniere pentru a reprezenta orice caracter unic;

Simbol % procent - pentru a indica orice succesiune arbitrară de caractere.

Predicatul LIKE este adevărat atunci când valoarea atributului specificat de numele coloanei din tuplu curent include valoarea specificată<шаблон>.

Predicatul NOT LIKE este adevărat atunci când valoarea atributului din tuplu curent nu o include pe cea dată<шаблон>.

· predicat NULL - necunoscut, nedefinit

Diagrama sintactică a predicatului este prezentată în Fig. 7.


Toate predicatele discutate anterior pot fi folosite în condițiile de căutare.

Lăsând deoparte introducerea noastră despre grupare pentru un moment, să aruncăm o privire mai atentă la primele trei rânduri ale instrucțiunii SELECT:

SELECTA- un cuvânt cheie care spune DBMS că această comandă este o solicitare. Toate interogările încep cu acest cuvânt urmat de un spațiu. Poate fi urmată de o metodă de eșantionare - cu duplicatele eliminate ( DISTINCT), sau fără ștergere ( TOATE, este implicit implicit). Aceasta este urmată de o listă de coloane separate prin virgulă pe care interogarea le selectează din tabele sau caracterul „ * ’ pentru a selecta întreaga linie. Orice coloană care nu este listată aici nu va fi inclusă în setul de date rezultat. Acest lucru, desigur, nu înseamnă că vor fi șterse sau informațiile lor vor fi șterse din tabele, deoarece interogarea nu afectează informațiile din tabele - arată doar datele.

DIN- un cuvânt cheie care trebuie să fie prezent în fiecare solicitare. Cuvântul cheie FROM este urmat de unul sau mai multe spații și apoi de o listă de tabele sursă care sunt utilizate în interogare. Numele tabelelor sunt separate prin virgule. Tabelelor li se pot da nume de alias, care pot fi utile pentru alăturarea unui tabel la el însuși sau pentru accesarea înregistrării curente a unei interogări exterioare dintr-o subinterogare imbricată (subinterogările imbricate nu sunt discutate aici). Un alias este un nume de tabel temporar care este utilizat numai în această interogare și nu este utilizat în continuare. Un alias este separat de numele tabelului principal prin cel puțin un spațiu. Diagrama de sintaxă a părții FROM este prezentată în Fig. 9.


Toate părțile ulterioare ale instrucțiunii SELECT sunt opționale.

· UNDE- un cuvânt cheie urmat de o condiție de predicat care determină acele înregistrări care vor fi incluse în setul de date de interogare rezultat.

Să luăm în considerare o relație de bază de date care modelează parcurgerea unei sesiuni într-o anumită instituție de învățământ. Fie ca acesta să fie format din trei relații , , . Vom presupune că acestea sunt reprezentate de tabelele R1, R2 și respectiv R3.

R1=(Nume, Disciplina, Clasa)

R2=(Nume, grup)

R3=(Grup, Disciplina)

Iată câteva exemple de utilizare a instrucțiunii SELECT.

· Lista tuturor grupelor (fără repetări) în care urmează să aibă loc examenele

SELECTARE DISTINCT Grupuri
DE LA R3

· Lista studenților care au promovat examenul DB cu note „excelent”.

SELECTAȚI numele complet
DE LA R1
UNDE Disciplina= „DB” ȘI Nota = 5

· O listă cu toți studenții care trebuie să ia ceva, împreună cu numele disciplinei.

SELECTA Nume complet, disciplină
DE LA R2, R3
UNDE R1.Grup = R2.Grup

Aici partea WHERE specifică condițiile pentru conectarea relațiilor R1 și R2. În lipsa condițiilor de îmbinare în partea UNDE, rezultatul va fi echivalent cu produsul cartezian extins și, în acest caz, fiecărui elev i-ar fi atribuite toate disciplinele din relația R2, și nu cele pe care trebuie să le parcurgă grupul său.

· Lista de slobi cu mai multe două

SELECTA Numele complet
DIN R1 a, R1 b
UNDE a.nume complet = b.nume completŞI
a.Disciplina <> b.DisciplinaŞI
a.Evaluare<= 2 ŞI b.Evaluare.<= 2

Aici am folosit alias-uri pentru a numi relația R1 a și b, deoarece pentru a înregistra termenii de căutare trebuie să lucrăm cu două instanțe ale acestei relații simultan.

Din aceste exemple se vede clar că logica operatorului de selecție (produs cartezian-selecție-proiecție) nu coincide cu ordinea descriere a datelor din acesta (mai întâi lista câmpurilor pentru proiecție, apoi lista tabelelor). pentru produsul cartezian, apoi condiția de îmbinare). Faptul este că SQL a fost dezvoltat inițial pentru a fi utilizat de către utilizatorul final și au încercat să-l apropie de un limbaj natural, și nu de un limbaj algoritmic. Desigur, engleza a fost aleasă ca limbă naturală, ca limbă internațională utilizată pe scară largă în calcul și programare. Din acest motiv, SQL provoacă inițial confuzie și iritare în rândul programatorilor profesioniști care încep să-l studieze și care sunt obișnuiți să vorbească cu o mașină în limbaje algoritmice.

Prezența valorilor nule nedefinite crește flexibilitatea procesării informațiilor stocate în baza de date. În exemplele noastre, putem presupune o situație în care un student a venit la examen, dar nu l-a promovat din anumite motive, în acest caz, nota la o disciplină are o valoare incertă pentru acest student; În această situație, puteți pune întrebarea: „Găsiți studenți care au venit la examen, dar nu l-au promovat, indicând numele disciplinei”. Declarația Select ar arăta astfel:

SELECTA Nume complet, disciplină

UNDE Nota ESTE NUL

Aș dori să fac imediat o rezervă că toate exemplele date mai devreme sunt condiționate. De ce? Nu vor funcționa în baze de date reale? Au gresit? Totul este corect aici, cu excepția numelor de atribute sau a coloanelor din tabel. Majoritatea SGBD-urilor (Sisteme de management al bazelor de date) nu permit denumirea coloanelor în limbile naționale, acestea sunt obiecte de bază de date și obiecte de limbă și necesită ca acestea să fie denumite conform convențiilor de denumire a identificatorului din acea limbă. Cel mai adesea, numele atributului poate fi o succesiune de litere și numere latine, începând cu o literă, care nu conține unele caractere speciale (de exemplu, spații, puncte, virgule, semne procentuale, % și alte caractere speciale) și având unele restricții privind lungime. Aceste restricții sunt diferite în diferite SGBD, de exemplu în MS SQL Server 2000 – lungimea unui nume de atribut poate ajunge la 128 de caractere. Numele lungi de atribute sunt incomode pentru scrierea unei interogări, dar numele foarte scurte cu o literă nu permit păstrarea semanticii semnificației unei coloane de tabel, așa că aleg un compromis și îl numesc scurt, dar convenabil, astfel încât să nu fie nevoie pentru a analiza descrierea completă a bazei de date atunci când scrieți fiecare interogare. În plus, numele atributelor, precum și numele altor obiecte, nu trebuie să se potrivească cu cuvintele cheie SQL - de ex. acele cuvinte care sunt incluse în operatorii limbii.

Prin urmare, din punct de vedere al corectitudinii, ar trebui să prezentăm schema bazei de date „Sesiune” în formular

R1=(St_name, Discipline, Mark)

R2=(Nume_Sf, grup_N)

R3=(N_grup, Disciplina)

Și modificați toate cererile în consecință.

Utilizarea funcțiilor agregate și a interogărilor imbricate într-o instrucțiune Select

Interogările pot calcula valoarea generalizată a grupului de câmpuri în același mod ca valoarea unui singur câmp. Acest lucru se face folosind funcții agregate. Funcțiile agregate produc o singură valoare pentru un întreg grup de tabele. Lista acestor funcții:

Funcțiile agregate sunt folosite în mod similar cu numele câmpurilor dintr-o instrucțiune SELECT, cu o singură excepție: ele iau numele câmpului ca argument. Numai câmpurile numerice pot fi utilizate cu funcțiile SUM și AVG. Atât câmpurile numerice, cât și cele de caractere pot fi utilizate cu funcțiile COUNT, MAX și MIN. Când sunt utilizate cu câmpuri de caractere, MAX și MIN le vor traduce în echivalentul ASCII și vor fi procesate în ordine alfabetică. Unele SGBD-uri permit utilizarea agregatelor imbricate, dar aceasta este o abatere de la standardul ANSI cu toate consecințele care decurg.

Revenind din nou la baza de date „Sesiune” (tabelele R1, R2, R3), aflăm numărul de examene promovate cu succes:

SELECTARE NUMĂR (*)
DE LA R1
UNDE Marcaj > 2;

Acest lucru este, desigur, diferit de selectarea unui câmp, deoarece returnează întotdeauna o singură valoare, indiferent de câte rânduri există în tabel. Din acest motiv, funcțiile și câmpurile agregate nu pot fi selectate în același timp decât dacă este utilizată o clauză specială GROUP BY.

Clauza GROUP BY vă permite să definiți un subset de valori, denumit grup și să aplicați o funcție de agregare acelui grup. Un grup este format din toate rândurile pentru care valorile câmpului de grupare specificate în clauza GROUP BY au aceeași valoare. Acest lucru face posibilă combinarea câmpurilor și a funcțiilor agregate într-o singură clauză SELECT. O diagramă de sintaxă pentru utilizarea funcțiilor de agregare este prezentată în Fig. 10. Funcțiile de agregare pot fi utilizate atât într-o expresie pentru afișarea rezultatelor pe rând. SELECTA, și în expresia pentru starea de procesare a grupurilor formate AVÂND. În acest caz, fiecare funcție agregată este calculată pentru fiecare grup selectat. Valorile obținute din calculul funcțiilor agregate pot fi folosite pentru afișarea rezultatelor corespunzătoare sau pentru a condiționa selecția grupurilor.

Când utilizați funcții de agregare, trebuie să vă amintiți că setul de rezultate poate conține numai valori de câmpuri de grupare și, eventual, valori de funcții agregate. Nu este permisă gruparea după o singură valoare și afișarea altor valori. Aceasta va fi o eroare de sintaxă.

De exemplu, o interogare ca aceasta va eșua întotdeauna:

Selectați A

Grupați după B

Serios, hai să ne dăm seama. Ce vrem să găsim? Încercăm să scoatem o valoare a coloanei O de la masă T, și în același timp efectuează gruparea după o altă coloană, coloană ÎN. Efectuăm gruparea - aceasta înseamnă că colectăm toate rândurile cu aceleași valori ale coloanei B într-un singur grup și apoi, și apoi nu este clar, afișăm valoarea coloanei A, dar într-un grup pot fi multe valori, diferite valori ale coloanei A. Deci ce valoare retragem? Acest lucru nu este de neînțeles nici pentru noi, nici pentru computer. De aceea refuză să îndeplinească o astfel de solicitare și afirmă că avem o eroare de sintaxă.


Să revenim la baza noastră de date Session, dar să mai adăugăm câteva atribute. În primul rând, pot exista omonimi printre studenți, așa că pentru a identifica un student vom folosi numele registrului studentului, care îl identifică întotdeauna în mod unic. Și în al doilea rând, să presupunem că un student poate face mai multe încercări de a promova un examen la aceeași disciplină, iar pentru a face acest lucru, vom introduce data următoarei încercări de promovare a examenului în relația R1. Și, în final, a treia adăugare, vom presupune că la universitatea noastră există multe grupuri care studiază în diferite specialități, apoi schema bazei noastre de date va fi următoarea

Sesiune (N_zach,Discipline,Mark,Data_ex)

SQL a adăugat funcții suplimentare care vă permit să calculați valori generalizate de grup. Pentru aplicarea funcțiilor agregate, se presupune o operație preliminară de grupare. Care este esența operațiunii de grupare? La grupare, întregul set de tupluri ale unei relații este împărțit în grupuri în care sunt colectate tupluri care au aceleași valori de atribut care sunt specificate în lista de grupare.

De exemplu, să grupăm relația R1 după valoarea coloanei Discipline. Vom obține 4 grupuri pentru care putem calcula niște valori de grup, precum numărul de tupluri din grup, valoarea maximă sau minimă a coloanei Scor.

Acest lucru se face folosind funcții agregate. Funcțiile agregate calculează o singură valoare pentru un întreg grup de tabele. O listă a acestor funcții este prezentată în Tabelul 5.7.

Tabelul 5.7.Funcții agregate

R1
Numele complet Disciplina Nota
Grupa 1 Petrov F.I. Baze de date
Sidorov K. A. Baze de date
Mironov A.V. Baze de date
Stepanova K. E. Baze de date
Krylova T. S. Baze de date
Vladimirov V. A. Baze de date
Grupa 2 Sidorov K. A. Teoria informației
Stepanova K. E. Teoria informației
Krylova T. S. Teoria informației
Mironov A.V. Teoria informației Nul
Grupa 3 Trofimov P. A. Rețele și telecomunicații
Ivanova E. A. Rețele și telecomunicații
Utkina N.V. Rețele și telecomunicații
Grupa 4 Vladimirov V. A. Limba engleză
Trofimov P. A. Limba engleză
Ivanova E. A. Limba engleză
Petrov F.I. Limba engleză i

Funcțiile agregate sunt folosite în mod similar cu numele câmpurilor dintr-o instrucțiune SELECT, cu o excepție: ele iau numele câmpului ca argument. Numai câmpurile numerice pot fi utilizate cu funcțiile SUM și AVG. Atât câmpurile numerice, cât și cele de caractere pot fi utilizate cu funcțiile COUNT, MAX și MIN. Când sunt utilizate cu câmpuri de caractere, MAX și MIN le vor traduce în codul ASCII echivalent și le vor procesa în ordine alfabetică. Unele SGBD-uri permit utilizarea agregatelor imbricate, dar aceasta este o abatere de la standardul ANSI cu toate consecințele care decurg.



De exemplu, puteți calcula numărul de studenți care au susținut examene la fiecare disciplină. Pentru a face acest lucru, trebuie să rulați o interogare grupată după câmpul „Disciplina” și să afișați ca rezultat numele disciplinei și numărul de rânduri din grup pentru această disciplină. Folosirea caracterului * ca argument pentru funcția COUNT înseamnă numărarea tuturor rândurilor din grup.

SELECT R1.Disciplina. CONTA(*)

GRUPARE PRIN R1 Disciplina

Rezultat:

Dacă vrem să numărăm numărul de persoane care au promovat examenul la orice disciplină, atunci trebuie să excludem valorile incerte din raportul inițial înainte de grupare. În acest caz, cererea va arăta astfel:

SELECT R1.Disciplina. CONTA(*)

DE LA R1 ​​UNDE R1.

Evaluarea NU ESTE NULĂ

GRUP DE Rl.Disciplina

Obtinem rezultatul:

În acest caz, linia cu studentul

Mironov A, V. Teoria informației Nul

nu vor fi incluse în setul de tupluri înainte de grupare, astfel încât numărul de tupluri din grup pentru disciplina „Teoria informației” va fi cu 1 mai mic.

De asemenea, puteți utiliza funcții de agregare fără operația de pre-grupare, caz în care întreaga relație este tratată ca un grup și poate fi calculată o valoare per grup pentru acest grup.



Revenind din nou la baza de date „Sesiune” (tabelele Rl, R2, R3), aflăm numărul de examene promovate cu succes:

WHERE Scor > 2:

Acest lucru este, desigur, diferit de selectarea unui câmp, deoarece returnează întotdeauna o singură valoare, indiferent de câte rânduri există în tabel. Argumentele pentru agregarea funcțiilor pot fi coloane individuale de tabel. Dar pentru a calcula, de exemplu, numărul de valori distincte ale unei anumite coloane dintr-un grup, trebuie să utilizați cuvântul cheie DISTINCT împreună cu numele coloanei. Să calculăm numărul de note diferite primite la fiecare disciplină:

SELECT Rl.Disciplina.

COUNT(Scor R1 DISTINCT)

UNDE R1.Evaluarea NU ESTE NUL

GRUP DE Rl.Disciplina

Rezultat:

Rezultatul poate include o valoare de câmp de grupare și mai multe funcții de agregare, iar condițiile de grupare pot folosi mai multe câmpuri. În acest caz, grupurile sunt formate conform unui set de câmpuri de grupare specificate. Operațiile cu funcții de agregare pot fi aplicate pentru a uni mai multe tabele sursă. De exemplu, să punem întrebarea: stabiliți pentru fiecare grupă și fiecare disciplină numărul de studenți care au promovat cu succes examenul și punctajul mediu la disciplină.

SELECT R2.Grup. R1.Disciplina. COUNT(*), AVP(evaluare)

UNDE Rl.nume complet = R2.nume complet ȘI

Rl.Evaluarea NU ESTE NUL SI

Evaluare Rl > 2

GROUP BY R2.Grup. Rl.Disciplina

Rezultat:

Nu putem folosi funcții agregate în clauza WHERE deoarece predicatele sunt evaluate în termeni de un singur rând, iar funcțiile agregate sunt evaluate în termeni de grupuri de rânduri.

Clauza GROUP BY vă permite să definiți un subset de valori dintr-un anumit câmp în termenii unui alt câmp și să aplicați o funcție de agregare subsetului. Acest lucru face posibilă combinarea câmpurilor și a funcțiilor agregate într-o singură clauză SELECT. Funcțiile de agregare pot fi utilizate atât în ​​expresia pentru ieșirea rezultatelor liniei SELECT, cât și în expresia pentru condiția de procesare a grupurilor HAVING formate. În acest caz, fiecare funcție agregată este calculată pentru fiecare grup selectat. Valorile obținute din calculul funcțiilor agregate pot fi folosite pentru afișarea rezultatelor corespunzătoare sau pentru a condiționa selecția grupurilor.

Să construim o interogare care să afișeze grupuri în care s-a primit mai mult de o notă negativă la o disciplină la examene:

SELECT R2.Grup

UNDE Rl.nume complet = R2.nume complet ȘI

Rl.Rating = 2

GROUP BY R2.Grup. R1.Disciplina

AVÂND numărare(*)> 1

Pe viitor, de exemplu, nu vom lucra cu baza de date „Sesiune”, ci cu baza de date „Bancă”, constând dintr-un tabel F, care stochează relația F care conține informații despre conturile din sucursalele unei anumite bănci:

F= ;

Q = (Sucursală, Oraș);

întrucât pe această bază se poate ilustra mai clar lucrarea cu funcţii agregate şi grupare.

De exemplu, să presupunem că vrem să găsim soldul total al conturilor bancare. Puteți face o interogare separată pentru fiecare dintre ele selectând SUM(Sold) din tabelul pentru fiecare ramură. GROUP BY, totuși, vă va permite să le puneți pe toate într-o singură comandă:

SELECT filiala, SUM

GRUPA DUPA Filiala:

GROUP BY aplică funcții agregate în mod independent pentru fiecare grup identificat prin valoarea câmpului Branch. Un grup este format din rânduri cu aceeași valoare a câmpului Branch, iar funcția SUM este aplicată separat pentru fiecare astfel de grup, adică soldul total al contului este calculat separat pentru fiecare ramură. Valoarea unui câmp căruia i se aplică GROUP BY are, prin definiție, o singură valoare per grup de ieșire, la fel ca rezultatul unei funcții agregate. Prin urmare, putem combina un agregat și un câmp într-o singură cerere. De asemenea, puteți utiliza GROUP BY cu mai multe câmpuri.

Să presupunem că am dori să vedem doar acele solduri totale ale conturilor care depășesc 5.000 USD. Pentru a vedea soldurile totale de peste 5.000 USD, trebuie să utilizați clauza HAVING. Clauza HAVING specifică criteriile utilizate pentru a elimina anumite grupuri din rezultat, la fel ca clauza WHERE pentru rândurile individuale.

Comanda corectă ar fi:

SELECTARE Sucursala, SUM(Rămas)

GRUPA PE Filiala

AVÂND SUM(Rămas) > 5000;

Argumentele dintr-o clauză HAVING urmează aceleași reguli ca și într-o clauză SELECT care utilizează GROUP BY. Acestea trebuie să aibă o valoare pentru fiecare grup de ieșiri.

Următoarea comandă va fi interzisă:

SELECT Branch.SUM(Rămas)

DIN F GRUP CU Filiala

HAVINGOpenDate = 27/12/1999;

Câmpul OpenDate nu poate fi utilizat într-o clauză HAVING deoarece poate avea mai mult de o valoare per grup de ieșire. Pentru a evita această situație, clauza HAVING ar trebui să facă referire numai la agregatele și câmpurile selectate de GROUP BY. Există o modalitate corectă de a face interogarea de mai sus:

SELECT filiala,SUMA(Rămas)

WHEREOpenDate = "27/12/1999"

GRUP PE Filiala;

Sensul acestei interogări este următorul: găsiți suma soldurilor pentru fiecare ramură de conturi deschisă la 27 decembrie 1999.

După cum sa menționat mai devreme, HAVING poate lua doar argumente care au o singură valoare per grup de ieșire. În practică, referințele la funcțiile agregate sunt cele mai comune, dar câmpurile selectate folosind GROUP BY sunt și ele valide. De exemplu, dorim să vedem soldurile totale din conturile sucursalelor din Sankt Petersburg, Pskov și Uryupinsk:

SELECT Branch.SUM(Rămas)

UNDE F.Filială = Q.Filială

GRUPA PE Filiala

HAVING Branch IN ("Sankt Petersburg". "Pskov". "Uriupinsk");

Prin urmare, numai specificațiile coloanelor specificate ca coloane de grupare în clauza GROUP BY pot fi utilizate direct în expresiile aritmetice predicate incluse în clauza de selecție a clauzei HAVING. Coloanele rămase pot fi specificate numai în specificațiile funcțiilor agregate COUNT, SUM, AVG, MIN și MAX, care în acest caz calculează o anumită valoare agregată pentru întregul grup de rânduri. Situația este similară cu subinterogările incluse în predicatele condiției de selecție a secțiunii HAVING: dacă subinterogarea folosește o caracteristică a grupului curent, atunci aceasta poate fi specificată doar prin referire la coloanele de grupare.

Rezultatul clauzei HAVING este un tabel grupat care conține numai acele grupuri de rânduri pentru care condiția de căutare evaluează la TRUE. În special, dacă o clauză HAVING este prezentă într-o expresie de tabel care nu conține un GROUP BY, atunci rezultatul executării acesteia va fi fie un tabel gol, fie rezultatul executării secțiunilor anterioare ale expresiei de tabel, tratate ca un singur grupați fără gruparea coloanelor.

Interogări SQL imbricate

Acum să revenim la baza de date „Sesiune” și să ne uităm la exemplul său de utilizare a interogărilor imbricate.

Cu SQL puteți imbrica interogări unul în celălalt. De obicei, interogarea interogă generează o valoare care este testată în predicatul interogării exterioare (în clauza WHERE sau HAVING) pentru a determina dacă este adevărată sau falsă. În combinație cu o subinterogare, puteți utiliza predicatul EXISTS, care returnează adevărat dacă rezultatul subinterogării nu este gol.

Atunci când este combinată cu alte caracteristici ale operatorului select, cum ar fi gruparea, o subinterogare este un instrument puternic pentru obținerea rezultatului dorit. În partea FROM a instrucțiunii SELECT, este permisă aplicarea sinonimelor numelor de tabel dacă, atunci când formăm o interogare, avem nevoie de mai multe instanțe ale unei anumite relații. Sinonimele sunt specificate folosind cuvântul cheie AS, care poate fi omis cu totul. Deci, partea FROM ar putea arăta astfel:

DE LA Rl AS A, Rl AS B

DE LA Rl A. Rl B:

ambele expresii sunt echivalente și sunt considerate a fi aplicații ale instrucțiunii SELECT la două instanțe ale tabelului R1.

De exemplu, să arătăm cum arată unele interogări către baza de date „Sesiune” în SQL:

  • Lista celor care au promovat toate examenele obligatorii.

WHERE Scor > 2

AVÂND NUMĂRĂ (*) = (SELECTARE NUMĂRĂ (*))

WHERE R2.Group=R3.Group AND full namea.full name)

Aici, interogarea încorporată determină numărul total de examene pe care trebuie să le susțină fiecare elev din clasa studentului și compară acest număr cu numărul de examene pe care le-a susținut studentul.

  • O listă cu cei care trebuiau să susțină examenul de bază de date, dar nu l-au susținut încă.

SELESTFIO

WHERE R2.Fpynna=R3.Group AND Discipline = "DB" ȘI NU EXISTĂ

(SELECTează numele complet FROM Rl WHERE nume complet=a.nume complet ȘI Disciplina = "DB")

Predicatul EXISTS (SubQuery) este adevărat atunci când subinterogarea nu este goală, adică conține cel puțin un tuplu, în caz contrar predicatul EXISTS este fals.

Predicatul NOT EXISTS este adevărat numai atunci când SubQuery este goală.

Observați cum NU EXISTĂ cu o interogare imbricată vă permite să evitați operația de diferență de relație. De exemplu, formularea unei interogări cu cuvântul „toate” se poate face ca cu un dublu negativ. Să luăm în considerare un exemplu de bază de date care modelează furnizarea de piese individuale de către furnizori individuali, este reprezentată de o relație SP „Furnizori-piese” cu diagramă;

SP (Număr_furnizor. Număr_piesă) P (Număr_piesă. Nume)

Așa se formulează răspunsul la cerere: „Găsiți furnizori care furnizează toate piesele”.

SELECTAȚI NUMĂRUL DISTINCT DE VENDOR_DIN SP SP1 UNDE NU EXISTĂ

(SELECTARE număr_parte

DIN P UNDE NU EXISTA

(SELECTARE * DIN SP SP2

WHERE SP2.supplier_number=SP1.supplier_number AND

sp2.part_number = P.part_number)):

De fapt, am reformulat această solicitare după cum urmează: „Găsiți furnizori astfel încât să nu existe piesă pe care să nu o furnizeze”. Trebuie remarcat faptul că această interogare poate fi implementată și prin funcții agregate cu o subinterogare:

SELECTAȚI DISTINCT Număr_furnizor

GROUP BY Număr_furnizor

AVÂND CounKDIstinct număr_parte) =

(SELECT Count(număr_parte)

Standardul SQL92 extinde operatorii de comparare la comparații multiple folosind cuvintele cheie ANY și ALL. Această extensie este utilizată atunci când se compară valoarea unei anumite coloane cu o coloană de date returnată de o subinterogare.

Cuvântul cheie ANY plasat în orice predicat de comparație înseamnă că predicatul va fi adevărat dacă pentru cel puțin o valoare din subinterogare predicatul de comparație este adevărat. Cuvântul cheie ALL necesită ca predicatul de comparație să fie adevărat atunci când este comparat cu toate rândurile din subinterogare.

De exemplu, să găsim studenți care au promovat toate examenele cu o notă nu mai mică de „bine”. Lucrăm cu aceeași bază de date „Sesiune”, dar la aceasta mai adăugăm o relație R4, care caracterizează livrarea lucrărilor de laborator pe parcursul semestrului:

R 1 = (Nume, Disciplina, Grad);

R2 = (nume complet, grup);

R 3 = (Grupuri, Disciplina)

R 4 = (Nume, Disciplina, Numar_luc_laborator, Nota);

Selectați R1. Nume complet din R1 Unde 4 > = Toate (Selectați Rl.Rating

Unde R1.Nume complet = R11.Nume complet)

Să ne uităm la un alt exemplu:

Selectați studenții a căror notă la examen nu este mai mică de cel puțin o notă din lucrările de laborator pe care le-au promovat la această disciplină:

Selectați R1.Nume

De la R1 unde R1.Rating>= ORICE (Selectați R4.Rating

Unde Rl.Disciplina = R4. Disciplina SI R1.Nume complet = R4.Nume complet)

Uniri exterioare SQL

Standardul SQL2 a extins conceptul de îmbinare condiționată. În standardul SQL1, la unirea relațiilor, s-au folosit doar condițiile specificate în partea WHERE a instrucțiunii SELECT și, în acest caz, doar tuplurile relațiilor originale concatenate de condițiile specificate, pentru care aceste condiții au fost definite și adevărate. , au fost incluse în relația rezultată. Cu toate acestea, în realitate, este adesea necesară unirea tabelelor în așa fel încât rezultatul să includă toate rândurile din primul tabel, iar în locul acelor rânduri din al doilea tabel pentru care nu este îndeplinită condiția de îmbinare, rezultatul ajunge cu valori nedefinite. Sau invers, toate rândurile din tabelul din dreapta (al doilea) sunt incluse, iar părțile lipsă ale rândurilor din primul tabel sunt completate cu valori nedefinite. Astfel de îmbinări au fost numite îmbinări exterioare, spre deosebire de îmbinările definite de standardul SQL1, care au ajuns să fie numite îmbinări interioare.

În general, sintaxa pentru partea FROM din standardul SQL2 este următoarea:

DIN<список исходных таблиц> |

< выражение естественного объединения > |

< выражение объединения >

< выражение перекрестного объединения > |

< выражение запроса на объединение >

<список исходных таблиц>::= <имя_таблицы_1>

[nume sinonim tabel_1] [...]

[,<имя_таблицы_п>[ <имя синонима таблицы_n> ] ]

<выражение естественного объединениям:: =

<имя_таблицы_1>NATURAL (INTERIOR | COMPLET | STÂNGA | DREAPTA ) ALĂTURĂ<имя_таблицы_2>

<выражение перекрестного объединениям: = <имя_таблицы_1>CROS JOIN<имя_таблицы_2>

<выражение запроса на объединением:=

<имя_таблицы_1>UNIUNEA UNIUNEA<имя_таблицы_2>

<выражение объединениям:= <имя_таблицы_1>( INTERIOR |

COMPLET | STÂNGA | DREAPTA) ÎNSCRIEȚI-VĂ (condiție ON)<имя_таблицы_2>

În aceste definiții, INNER înseamnă o îmbinare interioară, LEFT înseamnă o îmbinare la stânga, adică rezultatul include toate rândurile din tabelul 1, iar părțile tuplurilor rezultate pentru care nu au existat valori corespunzătoare în tabelul 2 sunt completate cu NULL valori (nedefinite). Cuvântul cheie RIGHT înseamnă o îmbinare la dreapta și spre deosebire de o îmbinare la stânga, în acest caz toate rândurile tabelului 2 sunt incluse în relația rezultată, iar părțile lipsă din tabelul 1 sunt completate cu valori nedefinite. Cuvântul cheie FULL definește un exterior complet uniți: atât stânga cât și dreapta. Cu o îmbinare exterioară completă, sunt efectuate atât îmbinările externe la dreapta, cât și la stânga, iar relația rezultată include toate rândurile din Tabelul 1, completate cu valori nule și toate rândurile din Tabelul 2, de asemenea, completate cu valori nule.

Cuvântul cheie EXTERIOR înseamnă exterior, dar dacă sunt date cuvintele cheie FULL, LEFT, RIGHT, atunci îmbinarea este întotdeauna considerată exterioară.

Să ne uităm la exemple de realizare a îmbinărilor exterioare. Să revenim la baza de date „Sesiune”. Să creăm o relație în care să rămână toate notele primite de toți elevii la toate examenele pe care au trebuit să le susțină. Dacă un student nu a promovat acest examen, atunci în loc de notă va avea o valoare nedeterminată. Pentru a face acest lucru, să efectuăm o îmbinare internă naturală secvențială a tabelelor R2 și R3 folosind atributul Grup și să conectăm relația rezultată cu o îmbinare naturală externă stângă cu tabelul R1 folosind coloanele Nume complet și Disciplina. În același timp, standardul permite utilizarea unei structuri paranteze, deoarece rezultatul uniunii poate fi unul dintre argumentele din partea FROM a instrucțiunii SELECT.

SELECT Rl.Nume complet, R1.Disciplina. Rl.Evaluare

DE LA (R2 NATURAL INNER JOIN R3) LEFT JOIN Rl FOLOSIRE (Nume. Disciplina)

Rezultat:

Numele complet Disciplina Nota
Petrov F.I. Baze de date
Sidorov K. A. Baze de date 4
Mironov L.V. Baze de date
Stepanova K. E. Baze de date
Krylova T. S. Baze de date
Vladimirov V. A. Baze de date
Petrov F.I. Teoria informației Nul
Sidorov K. A. Teoria informației
Mironov A.V. Teoria informației Nul
Stepanova K. E. Teoria informației
Krylova T. S. Teoria informației
Vladimirov V. A. Teoria informației Nul
Petrov F.I. Limba engleză
Sidorov K. A. Limba engleză Nul
Mironov A.V. Limba engleză Nul
Stepanova K. E. Limba engleză Nul
Krylova T. S. Limba engleză Nul
Vladimirov V. A. Limba engleză
Trofimov P. A. Rețele și telecomunicații
Ivanova E. A. Rețele și telecomunicații

Să luăm în considerare un alt exemplu, pentru aceasta luăm baza de date „Bibliotecă”. Este alcătuit din trei relații, numele atributelor aici sunt tastate cu litere latine, ceea ce este necesar în majoritatea DBMS-urilor comerciale.

CĂRȚI(ISBN, TITL. AUTOR. COAUTOR. YEARJZD, PAGES)

READER(NUM_READER. NAME_READER, ADRESS. HOOM_PHONE. WORK_PHONE. BIRTH_DAY)

EXEMPLARE (INV, ISBN, YES_NO. NUM_READER. DATE_IN. DATE_DUT)

Aici tabelul CĂRȚI descrie toate cărțile prezente în bibliotecă, are următoarele atribute:

  • ISBN - un cifr unic pentru carte;
  • TITL - titlul cărții;
  • AUTOR - prenumele autorului;
  • COAUTOR - numele de familie al coautorului;
  • YEARIZD - anul publicării;
  • PAGINI - numărul de pagini.

Tabelul READER stochează informații despre toți cititorii bibliotecii și conține următoarele atribute:

  • NUM_READER - număr unic de card de bibliotecă;
  • NAME_READER - numele de familie și inițialele cititorului;
  • ADRESA - adresa cititorului;
  • HOOM_PHONE - numărul de telefon de acasă;
  • WORK_PHONE - numărul de telefon de la serviciu;
  • BIRTH_DAY - data de naștere a cititorului.

Tabelul EXEMPLARE conține informații despre starea curentă a tuturor instanțelor tuturor cărților. Include următoarele coloane:

  • INV - numărul unic de inventar al unui exemplar de carte;
  • ISBN - cifra de carte, care determină ce fel de carte este și se referă la informații din primul tabel;
  • DA_NU - un semn al prezenței sau absenței acestei instanțe în bibliotecă în momentul curent;
  • NUM_READER - numărul cardului de bibliotecă dacă cartea este emisă cititorului, iar Null în caz contrar;
  • DATE_IN - dacă cititorul are cartea, atunci aceasta este data la care a fost eliberată cititorului; a DATE_OUT este data la care cititorul trebuie să returneze cartea la bibliotecă.

Să stabilim lista de cărți pentru fiecare cititor; dacă cititorul nu are cărți, atunci numărul exemplarului cărții este NULL. Pentru a efectua această căutare, trebuie să folosim o îmbinare exterioară stângă, adică luăm toate rândurile din tabelul READER și le unim cu rânduri din tabelul EXEMPLARE, dacă al doilea tabel nu are un rând cu numărul de card de bibliotecă corespunzător. , atunci în rândul relației rezultate, atributul EXEMPLARE.INV va avea o valoare NULL nedefinită:

SELECTAȚI READER.NAME_READER, EXEMPLARE.INV

DIN CITITORUL DREAPTA ÎNSCRIEȚI-VĂ EXEMPLARE PE READER.NUM_READER=EXEMPLARE.NUM_READER

Operația de îmbinare exterioară, așa cum am menționat deja, poate fi folosită pentru a forma surse în clauza FROM, deci, de exemplu, următorul text de interogare ar fi acceptabil:

DIN (CĂRȚILE RĂSCATĂ ÎNREGISTREAZĂ EXEMPLARE)

LEFT JOIN (EXEMPLU DE ALĂTURARE NATURALĂ DE CITITOR)

În același timp, pentru cărțile, din care nici un exemplar nu se află în mâinile cititorilor, valorile numărului cardului de bibliotecă și datele de colectare și returnare a cărții vor fi incerte.

O îmbinare încrucișată, așa cum este definită în standardul SQL2, corespunde unei operații de produs cartezian extins, adică o operație de îmbinare între două tabele în care fiecare rând al primului tabel este alăturat fiecărui rând al celui de-al doilea tabel.

Operațiunea cerere de fuziune este echivalentă cu operația de unire teoretică a mulțimilor în algebră. În acest caz, se păstrează cerința echivalenței schemelor relațiilor inițiale. O solicitare de alăturare este efectuată conform următoarei scheme:

SELECT - cerere

UNION SELECT - interogare

UNION SELECT - interogare

Toate interogările care participă la operația de alăturare nu trebuie să conțină expresii, adică câmpuri calculate.

De exemplu, trebuie să afișați o listă de cititori care dețin cartea „Idiot” sau cartea „Crimă și pedeapsă”. Iată cum va arăta cererea:

SELECTAȚI CITITORUL. NAME_READER

DE LA CITITOR, EXEMPLARE.CĂRȚI

BOOKS.TITLE = "Idiot"!}

SELECTAȚI READER.NAME_READER

DIN CITITOR, EXEMPLARE, CĂRȚI

WHERE EXEMPLARE.NUM_READER= READER.NUM_READER ȘI

EXEMPLRE.ISBN = BOOKS.ISBN AND

BOOKS.TITLE = „Crimă și pedeapsă"!}

În mod implicit, atunci când rulează o interogare de alăturare, tuplurile duplicate sunt întotdeauna excluse. Prin urmare, dacă există cititori care au ambele cărți în mână, acestea vor apărea totuși în lista rezultată o singură dată.

O interogare de alăturare se poate alătura oricărui număr de interogări originale.

Deci, la cererea anterioară puteți adăuga mai mulți cititori care țin în mână cartea „Castelul”:

SELECTAȚI CITITORUL. NAME_READER

DE LA CITITOR. EXEMPLARE, CĂRȚI

WHERE EXEMPLARE.NUM_READER= READER.NUM_READER ȘI .

EXEMPLRE.ISBN = BOOKS.ISBN AND

BOOKS.TITLE = "Castel"!}

În cazul în care trebuie să păstrați toate rândurile din relațiile sursă, trebuie să utilizați cuvântul cheie ALL în operația de îmbinare. Dacă sunt stocate tupluri duplicate, fluxul de execuție a interogării de unire va arăta astfel:

SELECT - cerere

SELECT - cerere

SELECT - cerere

Totuși, același rezultat poate fi obținut prin simpla schimbare a clauzei WHERE a primei părți a interogării originale, conectând condițiile locale cu o operație OR logică și eliminând tuplurile duplicate.

SELECTAȚI CITITORUL DISTINCT.NAME_READER

DE LA CITITOR. EXEMPLARE.CĂRȚI

WHERE EXEMPLARE.NUM_READER= READER.NUM_READER ȘI

EXEMPLRE.ISBN = BOOKS.ISBN AND

BOOKS.TITLE = "Idiot" OR!}

BOOKS.TITLE = „Crimă și pedeapsă" OR!}

BOOKS.TITLE = "Castel"!}

Niciuna dintre interogările originale dintr-o operațiune UNION nu trebuie să conțină o clauză ORDER BY, dar rezultatul unirii poate fi ordonat prin scrierea unei clauze ORDER BY care specifică lista coloanelor de ordonare după textul ultimei interogări SELECT inițiale.

Important! Dacă un parametru de funcție este de tip String și specifică un nume de câmp care conține spații, atunci numele câmpului trebuie să fie cuprins între paranteze drepte.
De exemplu: „[Numărul cifrei de afaceri]”.

1. Suma (Total)- calculează suma valorilor expresiilor transmise acestuia ca argument pentru toate înregistrările detaliate. Puteți trece un Array ca parametru. În acest caz, funcția va fi aplicată conținutului matricei.

Exemplu:
Sumă (Vânzări. Sumă Cifra de afaceri)

2. Numără - calculează numărul de valori, altele decât NULL. Puteți trece un Array ca parametru. În acest caz, funcția va fi aplicată conținutului matricei.

Sintaxă:
Cantitate([Diverse] Parametru)

Pentru a indica primirea de valori diferite, trebuie să specificați Distinct înainte de parametrul pentru metoda Cantității.

Exemplu:
Cantitate (Vânzări. Contraparte)
Cantitate (Vânzări diverse. Contraparte)

3. Maximum - obține valoarea maximă. Puteți trece un Array ca parametru. În acest caz, funcția va fi aplicată conținutului matricei.

Exemplu:
Maxim (Rămas.Cantitate)

4. Minimum - obține valoarea minimă. Puteți trece un Array ca parametru. În acest caz, funcția va fi aplicată conținutului matricei.

Exemplu:
Minim(Rămas.Cantitate)

5. Medie - Obține media pentru valorile non-NULL. Puteți trece un Array ca parametru. În acest caz, funcția va fi aplicată conținutului matricei.

Exemplu:
Medie (Cantitate rămasă)

6. Matrice - formează un tablou care conține valoarea parametrului pentru fiecare înregistrare detaliată.

Sintaxă:
Matrice ([diverse] expresii)

Puteți utiliza un tabel de valori ca parametru. În acest caz, rezultatul funcției va fi o matrice care conține valorile primei coloane din tabelul de valori transmise ca parametru. Dacă o expresie conține o funcție Array, atunci expresia este considerată a fi o expresie agregată. Dacă este specificat cuvântul cheie Diverse, matricea rezultată nu va conține valori duplicate.

Exemplu:
Matrice (contraparte)

7. ValueTable - generează un tabel de valori care conține atâtea coloane câte parametri există pentru funcție. Înregistrările detaliate sunt obținute din seturi de date necesare pentru a obține toate câmpurile implicate în expresiile parametrilor funcției.

Sintaxă:
ValueTable([Diverse] Expression1 [AS ColumnName1][, Expression2 [AS ColumnName2],...])

Dacă parametrii funcției sunt câmpuri reziduale, atunci tabelul de valori rezultat va conține valori pentru înregistrările pentru combinații unice de dimensiuni din alte perioade. În acest caz, valorile se obțin numai pentru câmpurile de sold, dimensiuni, conturi, câmpuri de perioadă și detaliile acestora. Valorile câmpurilor rămase din înregistrările din alte perioade sunt considerate egale cu NULL. Dacă o expresie conține funcția ValueTable, atunci această expresie este considerată a fi o expresie agregată. Dacă este specificat cuvântul cheie Diverse, atunci tabelul de valori rezultat nu va conține rânduri care conțin aceleași date. După fiecare parametru poate exista un cuvânt cheie opțional AS și un nume care va fi atribuit coloanei tabelului de valori.

Exemplu:
Tabel de valori (diverse nomenclaturi, caracteristici ale nomenclatoarelor ca caracteristici)

8. Colaps (GroupBy) - conceput pentru a elimina duplicatele dintr-o matrice.

Sintaxă:
Restrângere(Expresie, Numere de coloane)

Parametri:

  • Expresie- o expresie de tipul Array sau ValueTable, ale cărei valori ale elementelor trebuie să fie restrânse;
  • Numerele coloanelor- (dacă expresia este de tip ValueTable) tastați String. Numerele sau numele (separate prin virgule) ale coloanelor din tabelul de valori, printre care trebuie să căutați duplicate. Valoarea implicită este toate coloanele.
Exemplu:
Collapse(ValueTable(PhoneNumber, Address) ,"PhoneNumber");

9. GetPart - obține un tabel de valori care conține anumite coloane din tabelul de valori original.

Sintaxă:
GetPart(Expresie, ColumnNumbers)

Parametri:

  • Expresie- tip Tabel de Valori. Un tabel de valori din care să se obțină coloane;
  • Numerele coloanelor- tip String. Numerele sau numele (separate prin virgule) ale coloanelor din tabelul de valori care trebuie obținute.
Valoare returnată: Tabel de valori, care conține numai coloanele specificate în parametru.

Exemplu:
GetPart(Collapse(ValueTable(PhoneNumber, Address) ,"PhoneNumber"),"PhoneNumber");

10. Comanda - conceput pentru a organiza elemente de matrice și tabel de valori.

Sintaxă:
Aranjați (Expresie, Numere de coloane)

Parametri:

  • Expresie- Array sau Value Table din care trebuie să obțineți coloane;
  • Numerele coloanelor- (dacă expresia este de tip ValueTable) numere sau nume (separate prin virgule) ale coloanelor din tabelul de valori după care doriți să sortați. Poate conține direcția de comandă și necesitatea comenzii automate: Descrescător/Ascendente + Comandare automată.
Valoare returnată: Matrice sau ValueTable, cu elemente ordonate.

Exemplu:
Aranjează(ValueTable(PhoneNumber, Address, CallDate),"CallDate Descending");

11. JoinStrings - conceput pentru a combina șiruri într-o singură linie.

Sintaxă:
ConnectRows(Valoare, ElementSeparator, ColumnSeparator)

Parametri:

  • Sens- expresii care trebuie combinate într-o singură linie. Dacă este un Array, atunci elementele matricei vor fi combinate într-un șir. Dacă este un ValueTable, atunci toate coloanele și rândurile tabelului vor fi combinate într-un rând;
  • Separator de elemente- un șir care conține text pentru a fi folosit ca separator între elementele matricei și rândurile tabelului de valori. Implicit – caracter de avans de linie;
  • Separatoare de coloane- o linie care contine text care ar trebui folosit ca separator intre coloanele tabelului de valori. Implicit "; ".
Exemplu:
ConnectRows(ValueTable(PhoneNumber, Address));

12. GroupProcessing - returnează obiectul GroupProcessingDataCompositionData. În proprietatea Data a obiectului, valorile de grupare sunt plasate sub forma unui tabel de valori pentru fiecare expresie specificată în parametrul funcției Expresii. Când se utilizează gruparea ierarhică, fiecare nivel al ierarhiei este procesat separat. Valorile pentru înregistrările ierarhice sunt de asemenea plasate în date. Proprietatea CurrentItem a obiectului conține rândul tabelului de valori pentru care funcția este în prezent calculată.

Sintaxă:
GroupProcessing(expresii, expresii ierarhice, nume grup)

Parametri:

  • Expresii. Expresii de evaluat. O linie care conține expresii separate prin virgulă care trebuie evaluate. După fiecare expresie poate exista un cuvânt cheie opțional CUM și numele coloanei din tabelul de valori rezultat. Fiecare expresie formează o coloană în tabelul de valori a proprietății Data a obiectului DataCompositionGroupProcessingData.
  • ExpresiiIerarhii. Expresii de evaluat pentru înregistrările ierarhice. Similar cu parametrul Expressions, cu diferența că parametrul Hierarchy Expressions este utilizat pentru înregistrările ierarhice. Dacă parametrul nu este specificat, expresiile specificate în parametrul Expresie sunt utilizate pentru a calcula valorile pentru înregistrările ierarhice.
  • GroupName. Numele grupării în care se calculează gruparea de procesare. Linia. Dacă nu este specificat, calculul are loc în gruparea curentă. Dacă calculul se efectuează într-un tabel și parametrul conține un șir gol sau nu este specificat, atunci valoarea este calculată pentru grupare - rând. Compozitorul layout-ului, atunci când generează un layout de date, înlocuiește acest nume cu numele grupării în aspectul rezultat. Dacă gruparea nu este disponibilă, funcția va fi înlocuită cu o valoare NULL.
13. Toată lumea - dacă cel puțin o înregistrare are valoarea False, atunci rezultatul este Fals, în caz contrar, adevărat.

Sintaxă:
Fiecare (Expresie)

Parametru:

  • Expresie- tip boolean.
Exemplu:
Fiecare()

14. Oricare (Orice)- dacă cel puțin o înregistrare are valoarea True, atunci rezultatul este True, în caz contrar False

Sintaxă:
Orice (Expresie)

Parametru:

  • Expresie- tip boolean.
Exemplu:
Orice()

15. Abaterea standard a populației generale (Stddev_Pop) - calculează abaterea standard a populaţiei. Calculat folosind formula: SQRT(Varianța populației generale (X)).

Sintaxă:
Abaterea standard a populației generale (expresie)

Parametru:

  • Expresie- Tipul numărului.

Exemplu:

X1 2 3 4 5 6 7 8 9
Y7 1 2 5 7 34 32 43 87
SELECTAȚI Abaterea Standard a Populației Generale (Y) FROM Tabel
Rezultat: 805.694444

16. Deviația standard a eșantionului (Stddev_Samp) - calculează abaterea standard a eșantionului cumulat. Calculat folosind formula: SQRT(Sample Variance(X)).

Sintaxă:
Standard DeviationSample (Expresie)

Parametru:

  • Expresie- Tipul numărului.
Tip de returnare Număr.

Exemplu:

X1 2 3 4 5 6 7 8 9
Y7 1 2 5 7 34 32 43 87
SELECTAȚI StandardDeviationSamples(Y) FROM Table
Rezultat: 28.3847573

17. VarianceSamples (Var_Samp) - calculează diferența tipică a unei serii de numere fără a ține cont de valorile NULL din acest set. Calculat folosind formula: (Suma(X^2) - Suma(X)^2 / Cantitatea(X)) / (Cantitatea(X) - 1). Dacă Cantitatea (X) = 1, atunci este returnat NULL.

Sintaxă:
VarianceSamples(Expresie)

Parametru:

  • Expresie- Tipul numărului.
Exemplu:
SELECT Varianta Populației (Y) FROM Tabel
Rezultat: 716.17284

19. Covarianța populației generale (Covar_Pop) - calculează covarianța unui număr de perechi numerice. Calculat folosind formula: (Suma(Y * X) - Suma(X) * Suma(Y) / n) / n, unde n este numărul de perechi (Y, X) în care nici Y și nici X nu sunt NUL.

Sintaxă:
Covarianța populației (Y, X)

Parametri:

  • Y- tip Număr;
  • X- Tipul numărului.
Exemplu:
X1 2 3 4 5 6 7 8 9
Y7 1 2 5 7 34 32 43 87
SELECTAȚI CovariancePopulation(Y, X) FROM Table
Rezultat: 59.4444444

20. CovarianceSamples (Covar_Samp) - calculează diferența tipică a unei serii de numere fără a lua în considerare valorile NULL din acest set. Calculat folosind formula: (Suma(Y * X) - Suma(Y) * Suma(X) / n) / (n-1), unde n este numărul de perechi (Y, X) în care nici Y, nici X sunt NULL.

Sintaxă:
Eșantioane de covarianță (Y, X)

Parametri:

  • Y- tip Număr;
  • X- Tipul numărului.
Exemplu:
X1 2 3 4 5 6 7 8 9
Y7 1 2 5 7 34 32 43 87
SELECTAȚI Eșantioane de covarianță (Y, X) DIN Tabel
Rezultat: 66.875

21. Corelație (Corr) - calculează coeficientul de corelație al unui număr de perechi numerice. Calculat folosind formula: Covarianța populației (Y, X) / (Abaterea standard a populației (Y) * Abaterea standard a populației (X)). Perechile în care Y sau X sunt NULL nu sunt luate în considerare.

Sintaxă:
Corelație (Y, X)

Parametri:

  • Y- tip Număr;
  • X- Tipul numărului.
Exemplu:
X1 2 3 4 5 6 7 8 9
Y7 1 2 5 7 34 32 43 87
SELECTează corelația (X, Y) FROM Tabel
Rezultat: 0,860296149

22. RegressionSlope (Regr_Slope) - calculează panta dreptei. Calculat folosind formula: Covarianța populației generale (Y, X) / Varianța populației generale (X). Calculat fără a lua în considerare perechile care conțin NULL.

Sintaxă:
Panta de regresie (Y, X)

Parametri:

  • Y- tip Număr;
  • X- Tipul numărului.
Exemplu:
X1 2 3 4 5 6 7 8 9
Y7 1 2 5 7 34 32 43 87
SELECTAȚI Panta de regresie (Y, X) DIN Tabel
Rezultat: 8.91666667

23. RegressionIntercept (Regr_Intercept) - calculează punctul Y de intersecție al dreptei de regresie. Calculat folosind formula: Media (Y) - Panta de regresie (Y, X) * Media (X). Calculat fără a lua în considerare perechile care conțin NULL.

Sintaxă:
Segment de regresie (Y, X)

Parametri:

  • Y- tip Număr;
  • X- Tipul numărului.
Exemplu:
SELECTARE RegressionCount(Y, X) FROM Table
Rezultat: 9

25. RegresiaR2 (Regr_R2) - calculează coeficientul de determinare. Calculat fără a lua în considerare perechile care conțin NULL.

Sintaxă:
RegresiaR2(Y, X)

Parametri:

  • Y- tip Număr;
  • X- Tipul numărului.
Valoarea returnată:
  • Null - dacă Variația Populației Generale (X) = 0;
  • 1 - dacă variația populației generale (Y) = 0 și variația populației generale (X)<>0;
  • POW(Correlation(Y,X),2) - dacă variația populației generale(Y)>0 ȘI variația populației generale(X)<>0.
Exemplu:
X1 2 3 4 5 6 7 8 9
Y7 1 2 5 7 34 32 43 87
SELECTARE RegressionR2(Y, X) FROM Tabel
Rezultat: 0,740109464

26. RegressionAverageX (Regr_AvgX) - calculează media lui X după eliminarea perechilor X și Y în care fie X, fie Y este gol. Average(X) se calculează fără a lua în considerare perechile care conțin NULL.

Sintaxă:
Media de regresieX(Y, X)

Parametri:

  • Y- tip Număr;
  • X- Tipul numărului.
Exemplu:
X1 2 3 4 5 6 7 8 9
Y7 1 2 5 7 34 32 43 87
SELECTează RegressionMeanX(Y, X) FROM Table
Rezultat: 5

27. RegressionAverageY (Regr_AvgY) - calculează media lui Y după eliminarea perechilor X și Y în care fie X, fie Y este gol. Average(Y) se calculează fără a lua în considerare perechile care conțin NULL.

Sintaxă:
Media regresieiY(Y, X)

Parametri:

  • Y- tip Număr;
  • X- Tipul numărului.
Exemplu:
X1 2 3 4 5 6 7 8 9
Y7 1 2 5 7 34 32 43 87
SELECTARE RegressionMeanY(Y, X) FROM Table
Rezultat: 24.2222222

28. RegressionSXX (Regr_SXX) - se calculează folosind formula: RegresieCantitate(Y, X) * Dispersia Populației Generale(X). Calculat fără a lua în considerare perechile care conțin NULL.

Sintaxă:
RegresieSXX(Y, X)

Parametri:

  • Y- tip Număr;
  • X- Tipul numărului.
Returnează suma pătratelor expresiilor independente utilizate în modelul de regresie liniară. Funcția poate fi utilizată pentru a evalua validitatea statistică a unui model de regresie.

Exemplu:
SELECTAȚI regresieSYY(Y, X) FROM Tabel
Rezultat: 6445.55556

30. RegresieSXY (Regr_SXY) - calculat folosind formula: RegresieCantitate(Y, X) * Covarianța Populației Generale(Y, X). Calculat fără a lua în considerare perechile care conțin NULL.

Sintaxă:
RegresieSXY(Y,X)

Parametri:

  • Y- tip Număr;
  • X- Tipul numărului.
Exemplu:
X1 2 3 4 5 6 7 8 9
Y7 1 2 5 7 34 32 43 87
SELECTează regresiaSXY(Y, X) FROM Tabel
Rezultat: 535

31. Rang

Sintaxă:
PlaceInOrder(Comanda, HierarchyOrder, GroupName)

Parametri:

  • Comanda– tip String. Conține expresii în succesiunea cărora doriți să aranjați înregistrările de grup, separate prin virgule. Direcția de ordonare este controlată folosind cuvintele Crescător, Descendent. De asemenea, puteți urmări câmpul cu Comandă automată, ceea ce înseamnă că atunci când comandați link-uri, trebuie să utilizați câmpurile de comandă definite pentru obiectul referit. Dacă nu este specificată nicio secvență, atunci valoarea este calculată în secvența de grupare;
  • Ierarhia ordinii– tip String. Conține expresii de ordonare pentru înregistrările ierarhice;
  • GroupName– tip String. Numele grupării în care se calculează gruparea de procesare. Dacă nu este specificat, calculul are loc în gruparea curentă. Dacă calculul este efectuat într-un tabel și parametrul conține un șir gol sau nu este specificat, atunci valoarea este calculată pentru grupare - șirul. Compozitorul layout-ului, atunci când generează un layout de date, înlocuiește acest nume cu numele grupării din layout-ul rezultat. Dacă gruparea nu este disponibilă, atunci funcția va fi înlocuită cu o valoare NULL.
Dacă există două sau mai multe înregistrări într-o secvență cu aceleași valori de câmp de ordonare, atunci funcția returnează aceleași valori pentru toate înregistrările.

Exemplu:
PlaceInOrder("[Numărul cifrei de afaceri]")

32. ClasificareABC

Sintaxă:
ClasificareABC(Valoare, Număr de grupuri, Procent pentru grupuri, Nume Grup)

Parametri:

  • Sens– tip String. prin care trebuie calculată clasificarea. O linie care conține expresia;
  • Numărul de grupuri- Tipul numărului. Specifică numărul de grupuri în care trebuie împărțite;
  • PercentageForGroups- tip String. Cât de multe minus 1 trebuie împărțite în grupuri, separate prin virgule. Dacă nu este specificat, atunci automat;
  • GroupName- tip String. Numele grupării în care se calculează gruparea de procesare. Dacă nu este specificat, calculul are loc în gruparea curentă. Dacă calculul este efectuat într-un tabel și parametrul conține un șir gol sau nu este specificat, atunci valoarea este calculată pentru grupare - șirul. Compozitorul layout-ului, atunci când generează un layout de date, înlocuiește acest nume cu numele grupării din layout-ul rezultat. Dacă gruparea nu este disponibilă, atunci funcția va fi înlocuită cu o valoare NULL.
Rezultatul funcției va fi numărul clasei, începând de la 1, care corespunde clasei A.

Exemplu:
ClasificareABC(„Suma(Profit Brut)”, 3, „60, 90”)

Exemplul 21. Obțineți numărul total de furnizori (cuvânt cheie CONTA ):

SELECTAȚI COUNT(*) CA N

Rezultatul este un tabel cu o coloană și un rând care conține numărul de rânduri din tabelul P:

Utilizarea funcțiilor de agregare cu grupări

Exemplul 23 . Pentru fiecare parte, obțineți cantitatea totală furnizată (cuvânt cheie GROUP BY …):

SUM(PD.VOLUME) CA SM

GRUPĂ PRIN PD.DNUM;

Această solicitare va fi executată după cum urmează. În primul rând, rândurile tabelului sursă vor fi grupate astfel încât fiecare grup să conțină rânduri cu aceleași valori DNUM. Apoi, în cadrul fiecărui grup, câmpul VOLUME va fi însumat. Un rând din fiecare grup va fi inclus în tabelul rezultat:

Comentariu. În lista câmpurilor selectate ale unei instrucțiuni SELECT care conține o secțiune GROUP BY, puteți include numai funcții și câmpuri agregate, care sunt incluse în condiția de grupare. Următoarea interogare va genera o eroare de sintaxă:

SUM(PD.VOLUME) CA SM

GRUPĂ PRIN PD.DNUM;

Motivul erorii este că lista câmpurilor selectate include câmpul PNUM, care nu sunt incluse la secțiunea GROUP BY. Într-adevăr, fiecare grup rezultat de rânduri poate conține mai multe rânduri cu diverse valorile câmpului PNUM. Un rând total va fi generat din fiecare grup de rânduri. Cu toate acestea, nu există un răspuns clar la întrebarea ce valoare să alegeți pentru câmpul PNUM din linia finală.

Comentariu. Unele dialecte SQL nu consideră aceasta o eroare. Interogarea va fi executată, dar este imposibil de prezis ce valori vor fi introduse în câmpul PNUM din tabelul rezultat.

Exemplul 24 . Obțineți numere de piesă a căror cantitate totală furnizată depășește 400 (cuvânt cheie AVÂND …):

Comentariu. Condiția ca cantitatea totală furnizată să fie mai mare de 400 nu poate fi formulată în clauza WHERE, deoarece Nu puteți utiliza funcții agregate în această secțiune. Condițiile care utilizează funcții agregate ar trebui plasate într-o secțiune specială HAVING:

SUM(PD.VOLUME) CA SM

GRUPĂ PRIN PD.DNUM

AVÂND SUM(PD.VOLUME) > 400;

Ca rezultat, obținem următorul tabel:

Comentariu. O interogare poate conține atât condiții de selecție de rând în secțiunea WHERE, cât și condiții de selecție de grup în secțiunea HAVING. Condițiile de selecție a grupului nu pot fi mutate din secțiunea HAVING în secțiunea WHERE. La fel, condițiile de selecție a rândurilor nu pot fi mutate din secțiunea WHERE în secțiunea HAVING, cu excepția condițiilor care includ câmpuri din lista de grupare GROUP BY.

Utilizarea subinterogărilor

Un instrument foarte convenabil care vă permite să formulați interogări într-un mod mai ușor de înțeles este capacitatea de a utiliza subinterogări imbricate în interogarea principală.

Exemplul 25 . Obțineți o listă de furnizori a căror stare este mai mică decât starea maximă din tabelul furnizorilor (comparație cu o subinterogare):

UNDE P.STATYS<

(SELECTARE MAX.(STARE P.)

Comentariu. Deoarece câmpul P.STATUS este comparat cu rezultatul subinterogării, apoi subinterogarea trebuie formulată pentru a returna un tabel format exact un rând și o coloană.

Comentariu

    Executa dată subinterogare imbricată și obțineți valoarea maximă a stării.

    Scanați tabelul furnizor P, comparând de fiecare dată valoarea stării furnizorului cu rezultatul subinterogării și selectați doar acele rânduri în care starea este mai mică decât maximul.

Exemplul 26 . Folosind un predicat ÎN

(SELECTARE DISTINCT PD.PNUM

UNDE PD.DNUM = 2);

Comentariu. În acest caz, o subinterogare imbricată poate returna un tabel care conține mai multe rânduri.

Comentariu. Rezultatul executării cererii va fi echivalent cu rezultatul următoarei secvențe de acțiuni:

    Executa dată subinterogare imbricată și obțineți o listă de numere de furnizor care furnizează numărul de piesă 2.

    Scanați tabelul furnizor P, verificând de fiecare dată dacă numărul furnizorului este conținut în rezultatul subinterogării.

Exemplul 27 . Folosind un predicat EXISTA . Obțineți o listă cu furnizorii care furnizează piesa numărul 2:

PD.PNUM = P.PNUM ȘI

Comentariu. Rezultatul executării cererii va fi echivalent cu rezultatul următoarei secvențe de acțiuni:

    Scanați tabelul furnizor P, de fiecare dată când executați o subinterogare cu noua valoare a numărului furnizorului preluată din tabelul P.

    Includeți în rezultatul interogării numai acele rânduri din tabelul furnizorului pentru care subinterogarea imbricată a returnat un set nevid de rânduri.

Comentariu. Spre deosebire de cele două exemple anterioare, subinterogarea imbricată conține un parametru (link extern) transmis de la cererea principală - numărul furnizorului P.PNUM. Astfel de subinterogări sunt numite corelat (corelat ). O referință externă poate lua o valoare diferită pentru fiecare rând candidat evaluat de subinterogare, astfel încât subinterogarea trebuie re-execută pentru fiecare rând selectat în interogarea principală. Astfel de subinterogări sunt tipice pentru predicatul EXIST, dar pot fi folosite în alte subinterogări.

Comentariu. Se poate părea că interogările care conțin subinterogări corelate vor rula mai lent decât interogările cu subinterogări necorelate. De fapt, nu este așa, pentru că... modul în care utilizatorul a formulat cererea, nu defineste cum va fi executată această cerere. Limbajul SQL nu este procedural, ci declarativ. Aceasta înseamnă că utilizatorul care face cererea pur și simplu descrie, care ar trebui să fie rezultatul interogării, iar modul în care va fi obținut acest rezultat este responsabilitatea SGBD în sine.

Exemplul 28 . Folosind un predicat NU EXISTA . Obțineți o listă cu furnizorii care nu furnizează piesa numărul 2:

PD.PNUM = P.PNUM ȘI

Comentariu. La fel ca în exemplul anterior, aici este folosită o subinterogare corelată. Diferența este că interogarea principală va selecta acele rânduri din tabelul furnizorului pentru care subinterogarea imbricată nu returnează un singur rând.

Exemplul 29 . Obțineți numele furnizorilor care furnizează toate piesele:

SELECTAȚI NUME DISTINCT

PD.DNUM = D.DNUM AND

PD.PNUM = P.PNUM));

Comentariu. Această interogare conține două subinterogări imbricate și implementează o operație relațională diviziunile relaţiilor.

Subinterogarea cea mai interioara este parametrizata de doi parametri (D.DNUM, P.PNUM) si are urmatoarea semnificatie: selectati toate randurile care contin date despre livrarile furnizorului cu numarul PNUM al piesei cu numarul DNUM. Negația NU EXISTĂ indică faptul că acest furnizor nu furnizează această piesă. Subinterogarea externă a acestuia, care este un parametru imbricat și parametrizat P.PNUM, are sens: pentru a selecta o listă de piese care nu sunt furnizate de furnizorul PNUM. Negația NOT EXIST indică faptul că nu ar trebui să existe piese pentru un furnizor cu un număr PNUM care nu sunt furnizate de acel furnizor. Aceasta înseamnă exact că interogarea externă selectează doar furnizorii care furnizează toate piesele.