asociații Explicație sql se alăture stânga

Să considerăm un exemplu. Avem două tabele: utilizatori și departamente.

U) utilizatori D) departamente
nume id DJD id nume
-- ---- ---- -- ----
Vladimir 1 1 1 Vânzări
Anton 2 2 2 Suport






3 Alexander 6 martie Finanțe
4 Boris 02 aprilie Logistica
5 Yuri 4

SELECT u.id. u.name. d.name AS d_name
De la utilizatori u
INTERIOARĂ ÎNSCRIEȚI departamente d ON u.d_id = d.id

Interogarea returnează datele combinate, care se intersectează în condițiile specificate în interior înscrii la <..>.
În acest caz, condiția <таблица_пользователей>.<идентификатор_отдела> trebuie să se potrivească <таблица_отделов>.<идентификатор>

Ca urmare, nu:

- de Alexander (Divizia 6 - nu există)
- Departamentul de Finanțe (niciun utilizator)

ID-ul nume d_name
-- -------- ---------
1 Vânzări Vladimir
2 Suport Anton
4 Suport Boris
3 Yuri Logistics

alătura interioară INTERIOARE JOIN (sinonim cu JOIN, cuvinte cheie din interior poate fi omisă).

Alegeți numai datele care se potrivesc din tabelele alăturat.


Pentru a obține datele, care sunt potrivite pentru starea în parte, trebuie să fie utilizate

ALaTURAtI exterior - OUTER JOIN.

Astfel de date de returnare de asociere din ambele tabele (condiție de asociere se potrivesc), plus completează datele mostră rămase dintr-un tabel extern, care nu este adecvat pentru condiția, umplând valoarea NULL de date lipsă.

Există două tipuri de asociere externă OUTER JOIN - LEFT OUTER JOIN și RIGHT OUTER JOIN.

Ei lucrează în același mod, diferența constă în faptul că stânga - indică faptul că tabelul „extern“ va fi amplasat pe partea stângă (în acest exemplu, utilizatorii de masă).
cuvinte cheie exterior poate fi omisă. Înregistrare STÂNGA ÎNSCRIEȚI identice LEFT OUTER JOIN.

SELECT u.id. u.name. d.name AS d_name
De la utilizatori u
LEFT OUTER JOIN departamente d ON u.d_id = d.id

Obțineți lista completă a utilizatorilor și departamente sunt asociate.

ID-ul nume d_name
-- -------- ---------
1 Vânzări Vladimir
2 Suport Anton
3 Alexander NULL
4 Suport Boris
5 Yuri Logistics

UNDE d.id IS NULL

în eșantion va fi doar 3 # Alexandru, din moment ce el nu a fost numit departament.

Fig. Exterioară stânga se alăture filtrarea după domeniu


DREAPTA OUTER JOIN returnează lista departamentelor (tabelul din dreapta) și cartografiat utilizatori.

SELECT u.id. u.name. d.name AS d_name
De la utilizatori u
DREAPTA OUTER JOIN departamente d ON u.d_id = d.id

ID-ul nume d_name
-- -------- ---------
1 Vânzări Vladimir
2 Suport Anton
4 Suport Boris
NULL NULL Finanțe
5 Yuri Logistics

În plus, puteți filtra datele, pentru verificarea NULL.

SELECT d.id. d.name
De la utilizatori u
DREAPTA OUTER JOIN departamente d ON u.d_id = d.id
UNDE u.id este nul

În exemplul nostru, specificând, dacă u.id este nul, vom alege departamentele care nu sunt utilizatori înregistrați. (# 3 Finanțe)


Toate exemplele care le puteți testa aici:

FULL ÎNSCRIEȚI returnări `asociații obedinenie` STÂNGA și tabele DREAPTA, care combină rezultatele a două interogări.

CROSS ÎNSCRIEȚI se întoarce cruce (cartezian) combinarea celor două tabele. Rezultatul va fi o mostră din toate înregistrările din primul tabel asociat cu fiecare rând de-al doilea tabel. Punctul important este faptul că crucea nu este necesar să se specifice starea se alăture.

rânduri duplicate cu ajutorul ÎNSCRIEȚI

Când se utilizează o combinație incepatori uita de multe ori că eșantionul rezultat poate conține date duplicat!
Dacă aveți nevoie de o intrare, face unirea cu o subinterogare

SELECT T1. *. t2. * De la t1 left_table din stânga se alăture # 40; selectați * de la right_table în cazul în care some_column = 1 Limita 1 # 41; t2 ON t1.id = t2.join_id







Eșantionul de aceeași masă pentru mai multe condiții.

Luați în considerare sarcina Yandex:

Există un tabel de mărfuri.

CREATE TABLE `ya _ MĂRFURI # 40;
`Id` int # 40; 11 # 41; nesemnate AUTO_INCREMENT NOT NULL.
`Name` varchar # 40; 64 # 41; NOT NULL.
PRIMARY KEY # 40; `id` # 41;
# 41; MOTOARE = ​​InnoDB DEFAULT CHARSET = utf8;
inserați în valori ya_goods # 40; 1. „Mere“ # 41;. # 40; 2. „mere“ # 41;. # 40; 3. „pere“ # 41;. # 40; 4. „mere“ # 41;. # 40; 5. „portocale“ # 41;. # 40; 6. „pere“ # 41; ;

Acesta conține următoarele valori.

`Id`` name`
1 Mere
2 mere
3 Perele
4 Mere
5 Portocale
6 Perele

Scrie cerere care selectează o pereche unică `id` bunuri cu name` identical`, de exemplu:

În rezolvarea problemei trebuie remarcat faptul că perechea (x, y) și (y, x) - sunt identice.

SELECT ID1 g1.id. g2.id ID2
-- CONCAT ( '(', PUȚIN (g1.id, g2.id), '', CEA MAI MARE (g1.id, g2.id), ')') rândul
DE LA g1 ya_goods
INTERIOARĂ TE ya_goods g2 PE g1.name = g2.name
UNDE g1.id <> g2.id
GRUP DE PUȚIN # 40; g1.id. g2.id # 41;. CEL MAI MARE # 40; g1.id. g2.id # 41;
COMANDA PRIN g1.id;

-- sau fără grupuri (mai rapid)

SELECT CONCAT DISTINCT # 40; '('. PUȚIN # 40; g1.id. g2.id # 41;. ''. CEL MAI MARE # 40; g1.id. g2.id # 41;. ')' # 41; rând
DE LA g1 ya_goods
INTERIOARĂ TE ya_goods g2 PE g1.name = g2.name
UNDE g1.id <> g2.id

Se combină tabelul ya_goods pe același domeniu, `name`, gruparea acestora în funcție de identifikatoram unice și pentru a obține rezultatul.


mai multe multiple se alăture uniunii

Util pentru noi, dacă doriți să selectați mai mult de o valoare din tabelul de mai multe condiții.

Exemplu: Setul de opțiuni (greutate, volum) de mărfuri.
Produsele din tabelul de produse, opțiuni - product_options de masă, valori opțiune - product2options tabel
Este necesar: pentru a filtra produsele după dată, opțiunile disponibile

CREATE TABLE `products` # 40;
`Id` int # 40; 11 # 41;.
`Title` varchar # 40; 255 # 41;.
`Creat _ datetime at`
# 41;

CREATE TABLE produs `_ options` # 40;
`Id` int # 40; 11 # 41;.
`Name` varchar # 40; 255 # 41;
# 41;

CREATE TABLE `product2options` # 40;
`Produs _ int id` # 40; 11 # 41;.
`Opțiunea _ int id` # 40; 11 # 41;.
`Int Value` # 40; 11 # 41;
# 41;

INSERT INTO `produs _ options` # 40; `Id`. `name` # 41; VALORI
# 40; 11. „greutate“ # 41;.
# 40; 12. „Volum“ # 41; ;

INSERT INTO `product2options` # 40; `Produs _ id`. `Opțiunea _ id`. `value` # 41; VALORI
# 40; 11. 1. 200 # 41;.
# 40; 12. 1. 250 # 41;.
# 40; 2. 11. 35 # 41;.
# 40; 2. 12. 15 # 41;.
# 40; 11. 3. 310 # 41;.
# 40; 12. 3. 300 # 41;.
# 40; 2. 11. 45 # 41;.
# 40; 2. 12. 25 # 41; ;

Doar lista opțiunilor în ceea ce privește sub-interogare / dzhoine prin intermediul sau / și nu funcționează,
necesare pentru a efectua aderarea opțiuni tabele egal cu numărul acestor aceleași opțiuni (avem - 2: volum și greutate)

SELECT p. *. po1.name 'P1'. p2o1. valoare. po2.name 'P2'. p2o2. valoare

Din produse p

INTERIOARĂ TE product2options p2o1 PE p.id = p2o1.product_id
INTERIOARĂ TE product_options PO1 PE po1.id = p2o1.option_id

INTERIOARĂ TE product2options p2o2 PE p.id = p2o2.product_id
INTERIOARĂ TE product_options pO2 PE po2.id = p2o2.option_id

Combinațiile pot fi utilizate în conjuncție cu UPDATE.
De exemplu, avem masa de case (id, titlu, zona). Trebuie să selectați titlul, în cazul în care se întâlnește un număr m2` `Înlocuiți zona de câmp, în cazul în care este mai puțin. pentru că în MySQL suport otstutsutstvuet pentru expresii regulate, aveți nevoie de un pic pokoldovat pentru a localiza și substr.
În interogarea secundară, selectați datele de interes, cât și în etapa finală a datelor sunt actualizate în funcție de criteriile corespunzătoare (p5> zona).

baza de case UPDATE
INTERIOARĂ-TE # 40;
-- Antaris 1594 chirie birou m2 la viteza de 12.700 de ruble. m2 / an -> 1594
SELECT
id.
@baseString: = titlu titlu.
@areaTitleEnd: = LOCALIZA # 40; 'M2'. @baseString # 41; ca p2.
@tmpString: = ltrim # 40; INVERS # 40; SUBSTR # 40; @baseString. 1. @areaTitleEnd # 41; # 41; # 41; ca p3.
@areaTitleBegin: = STÂNGA # 40; @tmpString. - 1 + LOCALIZA # 40; ''. @tmpString # 41; # 41; ca p4.
@ Valoare: = CAST # 40; INVERS # 40; @areaTitleBegin # 41; ca UNSIGNED # 41; ca p5

DE LA ga_pageviews
UNDE din titlu ca „m2 %%“
# 41; Calc FOLOSIND # 40; `id` # 41;
bază SET. Zona = calc.p5
UNDE bază. zonă

Luați în considerare exemplul de eliminare duplicate. Există un tableWithDups tabel (id, e-mail). Este necesar să se elimine linia cu același e-mail:

ȘTERGE tableWithDups
DE LA tableWithDups
INTERIOARĂ-TE # 40;
SELECT MAX # 40; id # 41; AS lastId. e-mail
DE LA tableWithDups
GROUP prin e-mail
AVÂND COUNT # 40; * # 41> 1
# 41; dups ON dups.email = tableWithDups.email
UNDE tableWithDups.id

Ultimele două exemple nu sunt compatibile cu ANSI SQL, dar lucrează în mySQL.

În spatele articol au fost legate de asociatiile (precum și pentru anumite subiecte specifice bazdannyh):
SELF JOIN, full outer JOIN, CROSS JOIN (CROSS [EXTERIOR] APLICA), operațiunile stabilite UNION [ALL], INTERSECT, CU EXCEPȚIA etc.

@tags: SQL, MySQL, SQL Server, Oracle, SQLite, postgresql