Exemple de intersectare SQL. Operator pentru seturi de date CU EXCEPȚIA regulilor generale. Predicatul de existență SQL EXISTĂ

SQL oferă două moduri de a uni tabele:
  • prin specificarea tabelelor de alăturat (inclusiv subinterogări) în clauza FROM a instrucțiunii SELECT. Mai întâi, se unesc tabelele, iar abia apoi se aplică condițiilor specificate de clauza WHERE, agregare, ordonarea datelor etc., determinate de clauza GROUP BY etc.;
  • definirea unirii seturilor de rezultate produse prin prelucrarea instrucţiunii SELECT. În acest caz, cele două instrucțiuni SELECT sunt unite prin frază UNIUNE, INTERSECT, CU EXCEPTIA sau CORRESPONDENTE .

UNIUNE

Fraza UNIUNE combină rezultatele a două interogări conform următoarelor reguli:

Standardul nu impune nicio restricție privind ordonarea rândurilor în setul de rezultate. Deci, unele DBMS afișează mai întâi rezultatul primei interogări, apoi rezultatul celei de-a doua interogări. Oracle DBMS sortează automat înregistrările după prima coloană specificată, chiar dacă nu a fost creat niciun index pentru aceasta.

Pentru a specifica în mod explicit ordinea de sortare necesară, utilizați clauza ORDER BY. În acest caz, puteți utiliza atât numele coloanei, cât și numărul acesteia (Fig. 4.3).


Orez. 4.3.

Fraza UNIUNE ALL realizează unirea a două subinterogări în același mod ca clauza UNION, cu următoarele excepții:

  • rândurile care se potrivesc nu sunt eliminate din setul de rezultate generate;
  • interogările îmbinate apar secvenţial în setul de rezultate fără ordonare.

Când se combină mai mult de două interogări, parantezele pot fi folosite pentru a schimba ordinea în care este efectuată operația de îmbinare (Figura 4.4).


Orez. 4.4.

INTERSECT alăturați-vă

Fraza INTERSECT vă permite să selectați numai acele rânduri care sunt prezente în fiecare set de rezultate care este îmbinat. Pe fig. 4.5 prezintă un exemplu de combinare a interogărilor ca mulțimi care se intersectează.


Orez. 4.5.

CU EXCEPȚIA unirii

Fraza CU EXCEPTIA vă permite să selectați numai acele rânduri care sunt prezente în primul set de rezultate pentru a fi îmbinate, dar care nu sunt prezente în al doilea set de rezultate.

Expresii INTERSECTși CU EXCEPTIA ar trebui să fie acceptat numai la nivelul complet de conformitate SQL-92. Deci, niște DBMS în loc de expresie

Există o singură regulă importantă pentru a folosi instrucțiunea EXCEPT de reținut.

Ordinea, numărul și tipurile de date ale coloanelor trebuie să fie de același tip în toate interogările.

Conform standardului ANSI, operatorii de set UNION și EXCEPT au aceeași prioritate, dar operatorul INTERSECT este evaluat înaintea celorlalți operatori de set. Vă recomandăm să controlați în mod explicit prioritatea operatorului folosind paranteze. Aceasta este în general o practică foarte bună.

Conform standardului ANSI, o singură clauză ORDER BY poate fi utilizată într-o interogare. Introduceți-l la sfârșitul ultimei instrucțiuni SELECT. Pentru a evita ambiguitatea în specificarea coloanelor și tabelelor, asigurați-vă că atribuiți același alias tuturor coloanelor din tabel care se potrivesc. De exemplu:

SELECT au_lname AS „nume”, au_fname AS „prenume” FROM autori, EXCEPTĂ SELECT emp_lname AS „nume”, emp_fname AS „prenume” FROM angajați ORDER BY nume, prenume;

În plus, deoarece coloanele pot fi specificate în fiecare listă de coloane cu tipuri de date compatibile corespunzător, diferitele platforme RDBMS pot avea moduri diferite de a trata coloanele de lungimi diferite. De exemplu, dacă coloana au_lname din prima interogare din exemplul anterior este semnificativ mai lungă decât coloana emp_lname din a doua interogare, atunci diferite platforme pot avea reguli diferite pentru a determina lungimea rezultatului final. Dar, în general, platformele vor alege o dimensiune mai lungă (și mai puțin restrictivă) pentru rezultat.

Fiecare RDBMS își poate aplica propriile reguli pentru utilizarea unui nume de coloană în cazul în care numele din listele de coloane diferă. În general, sunt folosite numele coloanelor primei interogări.

Tipurile de date nu trebuie să fie identice, dar trebuie să fie compatibile. De exemplu, tipurile CHAR și VARCHAR sunt compatibile. În mod implicit, setul de rezultate din fiecare coloană va folosi dimensiunea corespunzătoare celui mai mare tip din fiecare poziție particulară. De exemplu, o interogare care preia date din coloanele care conțin valori de tipul VARCHAR(IO) și VARCHAR(15) va folosi tipul și dimensiunea lui VARCHAR(15).

Niciuna dintre platforme nu acceptă clauza CORRESPONDENȚĂ )) CU EXCEPȚIA

(SELECTARE statemenr.2 | VALUES (expressionl, expression2 [, ...])) CU EXCEPȚIA

Vă permite să specificați una sau mai multe coloane specificate manual care sunt incluse în setul de rezultate final. (Acesta se numește constructor de rând.) Clauza VALUES trebuie să specifice exact atâtea coloane câte sunt specificate în interogările instrucțiunilor EXCEPT. Deși instrucțiunea EXCEPT DISTINCT nu este acceptată, EXCEPT este echivalentul funcțional. Clauza CORRESPONDANT nu este acceptată. De asemenea, tipurile de date LONG VARCHAR, LONG VARGRAPHIC, BLOB, CLOB, DBCLOB, DATALINK și tipurile de structură nu sunt utilizate într-o clauză EXCEPT, dar pot fi utilizate într-o clauză EXCEPT ALL.

Dacă setul de rezultate are o coloană care are același nume în toate instrucțiunile SELECT, atunci numele respectiv este folosit ca nume final pentru coloana returnată de instrucțiune. Dacă o anumită coloană este denumită diferit în instrucțiuni SELECT diferite, atunci trebuie să redenumiți coloana în toate interogările folosind aceeași clauză alias AS în toate interogările.

Dacă sunt utilizați mai mulți operatori într-o singură interogare pentru a lucra cu seturi de date, atunci cel inclus în paranteze este executat mai întâi. După aceea, ordinul de execuție va fi de la stânga la dreapta. Cu toate acestea, toate instrucțiunile INTERSECT sunt executate înaintea instrucțiunilor UNION și EXCEPT. De exemplu:

SELECT empno FROM angajat WHERE workdept LIKE "E%" EXCEPT SELECT empno FROM emp_act WHERE projno IN (TF1000", TF2000", -AD3110") UNION VALUES ("AA0001"), ("AB0002"), ("AC0003");

Exemplul de mai sus preia ID-urile tuturor angajaților care lucrează în departamentul care începe cu „E” din tabelul de angajați, apoi elimină ID-urile celor care lucrează în proiectele IF1000, IF200” și AD3110 din tabelul de conturi angajați (emp_act). , trei ID-uri suplimentare, AA0001, AB0002 și AC0003, sunt adăugate utilizând operatorul de set UNION.

MySQL

MySQL nu acceptă instrucțiunea EXCEPT. Alternativ, puteți utiliza operatorii NOT IN sau NOT EXISTS.

Instrucțiunea INTERSECT preia rânduri identice din seturile de rezultate ale uneia sau mai multor interogări. În unele privințe, operatorul INTERSECT este foarte asemănător cu INNER JOIN.

INTERSECT aparține clasei de operatori pentru lucrul cu seturi de date (operator set). Alți astfel de operatori includ EXCEPT și UNION. Toți operatorii setului de date sunt folosiți pentru a manipula seturile de rezultate a două sau mai multe interogări în același timp, de unde și numele lor.

Sintaxă SQL2003

Nu există o limită tehnică a numărului de interogări într-o instrucțiune INTERSECT. Sintaxa generală este următoarea.

INTERSECT

]INTERSECT

Cuvinte cheie

Sunt incluse rânduri duplicate din toate seturile de rezultate.

DISTINCT

Rândurile duplicat sunt eliminate din toate seturile de rezultate înainte ca compararea să fie efectuată de instrucțiunea INTERSECT. Coloanele cu valori NULL sunt considerate duplicate. Dacă nu sunt specificate nici ALL, nici DISTINCT, DISTINCT este considerat implicit.

CORESPUNZĂTOR

Specifică faptul că vor fi returnate numai coloanele care au același nume în ambele interogări, chiar dacă ambele interogări folosesc caracterul wildcard (*).

Specifică că vor fi returnate numai coloanele numite, chiar dacă interogările găsesc alte coloane cu nume care se potrivesc. Această clauză trebuie utilizată împreună cu cuvântul cheie CORRESPONDING.

Reguli generale

Există o singură regulă importantă de reținut atunci când lucrați cu operatorul INTERSECT.

Ordinea și numărul de coloane din toate interogările trebuie să fie aceleași. Tipurile de date ale coloanelor corespunzătoare trebuie, de asemenea, să fie compatibile.

De exemplu, tipurile CHAR și VARCHAR sunt compatibile. În mod implicit, setul de rezultate din fiecare coloană va folosi dimensiunea corespunzătoare celui mai mare tip din fiecare poziție particulară.

Nicio platformă nu acceptă clauza CORRESPONDANT.

Conform standardului ANSI, operatorul INTERSECT are o prioritate mai mare decât alți operatori setați, deși precedența unor astfel de operatori este tratată diferit pe platforme diferite. Puteți controla în mod explicit prioritatea operatorului folosind paranteze. În caz contrar, SGBD-ul le poate executa în ordine de la stânga la dreapta sau de la primul până la ultimul.

Conform standardului ANSI, o singură clauză ORDER BY poate fi utilizată într-o interogare. Introduceți-l la sfârșitul ultimei instrucțiuni SELECT. Pentru a evita ambiguitatea în specificarea coloanelor și tabelelor, asigurați-vă că atribuiți același alias tuturor coloanelor din tabel care se potrivesc. De exemplu:

Pe platformele care nu acceptă operatorul INTERSECT, îl puteți înlocui cu o subinterogare FULL JOIN.

SELECT a.au_lname AS „nume”, a.au_fname AS „prenume” FROM autori AS a INTERSECT SELECT e.emp_lname AS „nume”, e.emp_fname AS „prenume” FROM angajați AS e ORDER BY nume, prenume;

Deoarece tipurile de date ale coloanelor din diferite instrucțiuni INTERSECT pot fi compatibile, diferite platforme RDBMS pot avea moduri diferite de a trata coloanele de lungimi diferite. De exemplu, dacă coloana aujname din prima interogare din exemplul anterior este semnificativ mai lungă decât coloana empjname din a doua interogare, atunci diferite platforme pot avea reguli diferite pentru a determina lungimea rezultatului final. Dar, în general, platformele vor alege o dimensiune mai lungă (și mai puțin restrictivă) pentru rezultat.

Fiecare RDBMS își poate aplica propriile reguli pentru utilizarea unui nume de coloană în cazul în care numele din listele de coloane diferă. În mod obișnuit, sunt folosite numele coloanelor primei interogări.

DB2

Platforma DB2 acceptă cuvintele cheie ANSI INTERSECT și INTERSECT ALL plus o clauză VALUES opțională.

(instrucțiune._SELECT_7 | VALORI (expr7 [, ...])) INTERSECT

] (instrucțiune_SCJ_2 | VALORI (expr2 [, ...])) INTERSECT

Deși instrucțiunea INTERSECT DISTINCT nu este acceptată, echivalentul funcțional este INTERSECT. Clauza CORRESPONDANT nu este acceptată.

În plus, tipurile de date LONG VARCHAR, LONG VARGRAPHIC, BLOB, CLOB, DBCLOB, DATALINK și tipurile de structură nu sunt utilizate într-o clauză INTERSECT, dar pot fi utilizate într-o clauză INTERSECT ALL.

Dacă setul de rezultate are o coloană care are același nume în toate instrucțiunile SELECT, atunci numele respectiv este folosit ca nume final pentru coloana returnată de instrucțiune. Cu toate acestea, dacă în interogări sunt folosite nume de coloane diferite, platforma DB2 va genera un nou nume pentru coloana rezultată. După aceea, devine inutilizabil în clauzele ORDER BY și FOR UPDATE.

Dacă sunt utilizați mai mulți operatori într-o singură interogare pentru a lucra cu seturi de date, atunci cel inclus în paranteze este executat mai întâi. După aceea, ordinul de execuție va fi de la stânga la dreapta. Cu toate acestea, toate instrucțiunile INTERSECT sunt executate înaintea instrucțiunilor UNION și EXCEPT, de exemplu:

SELECT empno FROM angajat WHERE workdept LIKE "E%" INTERSECT (SELECT empno FROM emp_act WHERE projno IN ("IF1000", "IF2000", "AD3110") UNION VALUES ("AA0001"), ("AB0002"), ("AC0003") "))

Exemplul de mai sus preia ID-urile angajaților tuturor angajaților din departament al căror nume începe cu „E” din tabelul de angajați. Cu toate acestea, identificatorii sunt preluați numai dacă există și în tabelul contului angajat numit emp_act și sunt implicați în proiectele IF1000, IF200" și AD3110.