O îmbinare interioară necesită ca fiecare rând din cele două tabele îmbinate să aibă valori de coloană potrivite și este o operație de îmbinare utilizată în mod obișnuit în aplicații, dar nu ar trebui să se presupună că este cea mai bună alegere în toate situațiile. Îmbinarea interioară creează un nou tabel de rezultate prin combinarea valorilor coloanei a două tabele (A și B) bazate pe predicatul de îmbinare. Interogarea compară fiecare rând al lui A cu fiecare rând al lui B pentru a găsi toate perechile de rânduri care satisfac predicarea de asociere. Când predicatul de asociere este satisfăcut prin potrivirea valorilor care nu sunt NULL, valorile coloanei pentru fiecare pereche de rânduri potrivite de A și B sunt combinate într-un rând de rezultate.
Rezultatul asocierii poate fi definit ca rezultatul preluării produsului cartezian (sau Îmbinare încrucișată) din toate rândurile din tabele (combinând fiecare rând din tabelul A cu fiecare rând din tabelul B) și apoi returnând toate rândurile care satisfac predicatul de îmbinare. Implementările SQL actuale utilizează în mod normal alte abordări, cum ar fi îmbinările hash sau sort-merge join, deoarece calculul produsului cartezian este mai lent și ar necesita adesea o cantitate de memorie prohibitiv de mare pentru a stoca.
SQL specifică două sintactice diferite modalități de exprimare a îmbinărilor: „notația de asociere explicită” și „notația de asociere implicită”. „Notarea de asociere implicită” nu mai este considerată o bună practică, deși sistemele de baze de date încă o acceptă.
„Notarea de asociere explicită” folosește cuvântul cheie JOIN
, opțional precedat de cuvântul cheie INNER
, pentru a specifica tabelul de asociat și de cuvântul cheie ON
pentru a specifica predicatele pentru asociere, ca în următorul exemplu:
SELECT employee.LastName, employee.DepartmentID, department.DepartmentName FROM employee INNER JOIN department ONemployee.DepartmentID = department.DepartmentID;
Employee.LastName |
Employee.DepartmentID |
Department.DepartmentName |
Robinson |
34 |
Clerical |
Jones |
33 |
Inginerie |
Smith |
34 |
Clerical |
Heisenberg |
33 |
Inginerie |
Rafferty |
31 |
Vânzări |
„Notarea implicită de îmbinare” listează pur și simplu t tabelele pentru alăturare, în clauza FROM
a declarației SELECT
, folosind virgule pentru a le separa. Astfel, specifică o îmbinare încrucișată, iar clauza WHERE
poate aplica predicate de filtrare suplimentare (care funcționează comparabil cu predicatele de îmbinare din notația explicită).
Următorul exemplu este echivalent cu cel precedent, dar de data aceasta folosind notația de asociere implicită:
SELECT employee.LastName, employee.DepartmentID, department.DepartmentName FROM employee, departmentWHERE employee.DepartmentID = department.DepartmentID;
Interogările date în exemple de mai sus se vor alătura tabelelor Angajați și Departament folosind coloana Departamentul ID din ambele tabele. În cazul în care ID-ul departamentului acestor tabele se potrivește (adică predicarea de asociere este îndeplinită), interogarea va combina coloanele LastName, DepartmentID și DepartmentName din cele două tabele într-un rând de rezultate. În cazul în care ID-ul departamentului nu se potrivește, nu este generat niciun rând de rezultate.
Astfel rezultatul executării interogării de mai sus va fi:
Employee.LastName |
Employee.DepartmentID |
Department.DepartmentName |
Robinson |
34 |
Clerical |
Jones |
33 |
Inginerie |
Smith |
34 |
Clerical |
Heisenberg |
33 |
Inginerie |
Rafferty |
31 |
Vânzări |
Angajatul „Williams” și departamentul „Marketing” nu apar în rezultatele executării interogării. Niciunul dintre acestea nu are rânduri potrivite în celălalt tabel respectiv: „Williams” nu are departament asociat și niciun angajat nu are ID-ul departamentului 35 („Marketing”). În funcție de rezultatele dorite, acest comportament poate fi o eroare subtilă, care poate fi evitată prin înlocuirea îmbinării interioare cu o îmbinare exterioară.
Unire interioară și valori NULL Editare
Programatorii ar trebui să ia o atenție deosebită la îmbinarea tabelelor pe coloane care pot conține valori NULL, deoarece NULL nu se va potrivi niciodată cu nicio altă valoare (nici măcar NULL în sine), cu excepția cazului în care condiția de asociere utilizează în mod explicit un predicat de combinație care verifică mai întâi dacă coloanele de asociere sunt NOT NULL
înainte de a aplica condițiile predicate rămase. Unirea interioară poate fi utilizată în siguranță numai într-o bază de date care impune integritatea referențială sau în cazul în care coloanele de asociere sunt garantate să nu fie NULL. Multe baze de date relaționale de procesare a tranzacțiilor se bazează pe standarde de actualizare a datelor de atomizare, consistență, izolare, durabilitate (ACID) pentru a asigura integritatea datelor, făcând îmbinările interioare o alegere adecvată. Cu toate acestea, bazele de date ale tranzacțiilor au, de obicei, și coloane de îmbinare dorite, care pot fi NULL.Multe baze de date relaționale de raportare și depozite de date folosesc volum mare de extragere, transformare, încărcare (ETL) actualizări de lot care fac integritatea referențială dificilă sau imposibil de aplicat, rezultând în coloane potențiale de unire NULL pe care un autor de interogare SQL nu le poate modifica și care determină omiterea îmbinărilor interioare date fără indicii de eroare. Alegerea utilizării unei îmbinări interioare depinde de proiectarea bazei de date și de caracteristicile datelor. O îmbinare exterioară stângă poate fi înlocuită de obicei cu o îmbinare interioară atunci când coloanele de îmbinare dintr-un singur tabel pot conține valori NULL.
Orice coloană de date care poate fi NULL (goală) nu trebuie folosită niciodată ca o legătură într-un îmbinare interioară, cu excepția cazului în care rezultatul intenționat este eliminarea rândurilor cu valoarea NULL. Dacă coloanele de asociere NULL urmează să fie eliminate în mod deliberat din setul de rezultate, o asociere interioară poate fi mai rapidă decât o asociere exterioară, deoarece asocierea tabelului și filtrarea se fac într-un singur pas. În schimb, o îmbinare interioară poate avea ca rezultat o performanță dezastruos de lentă sau chiar o blocare a serverului atunci când este utilizată într-o interogare de volum mare în combinație cu funcțiile bazei de date într-o clauză SQL Where. O funcție într-o clauză SQL Where poate duce la ignorarea bazei de date a indexurilor de tabel relativ compacte. Baza de date poate citi și se pot alătura coloanele selectate din ambele tabele înainte de a reduce numărul de rânduri folosind filtrul care depinde de o valoare calculată, rezultând o cantitate relativ mare de procesare ineficientă.
Când un set de rezultate este produs prin alăturarea mai multor tabele, inclusiv tabele master utilizate pentru a căuta descrieri de text complet ale codurilor numerice de identificare (un tabel de căutare), o valoare NULL în oricare dintre tastele străine poate duce la eliminarea întregului rând din setul de rezultate, fără indicii de eroare. O interogare SQL complexă care include una sau mai multe îmbinări interioare și mai multe îmbinări exterioare are același risc pentru valorile NULL din coloanele de legături de îmbinare interioare.
Un angajament față de codul SQL care conține îmbinări interioare presupune că coloanele de îmbinare NULL nu vor fi să fie introdus prin viitoare modificări, inclusiv actualizări ale furnizorilor, modificări de proiectare și procesare în bloc în afara regulilor de validare a datelor aplicației, cum ar fi conversiile de date, migrațiile, importurile în bloc și îmbinările.
Se pot clasifica în continuare îmbinările interioare ca echi-join, ca îmbinări naturale sau ca îmbinări încrucișate.
Equi-joinEdit
Un echi-join este un tip specific de îmbinare bazată pe comparator, care folosește doar comparații de egalitate în unirea-predicat. Utilizarea altor operatori de comparație (cum ar fi <
) descalifică o unire ca echi-join. Interogarea de mai sus a furnizat deja un exemplu de equi-join:
SELECT *FROM employee JOIN department ON employee.DepartmentID = department.DepartmentID;
Putem scrie echi-join ca mai jos,
SELECT *FROM employee, departmentWHERE employee.DepartmentID = department.DepartmentID;
Dacă co Lumnele dintr-o echi-join au același nume, SQL-92 oferă o notație opțională pentru scurtarea expresiei echi-join, prin intermediul construcției USING
:
SELECT
read more