Обяснение асоциации SQL присъединят ляв

Нека разгледаме един пример. В момента има две таблици: потребители и отдели.

U) потребители D) катедри
идентификатор име d_id име идентификатор
-- ---- ---- -- ----
Владимир 1 1 1 Продажби
Антон 2 2 2 Поддръжка






3 Александър 06 март финансите
4 Борис 2 април Логистика
5 Юри 4

SELECT u.id. u.name. d.name AS d_name
От потребителите ф
INNER JOIN отдели D ON u.d_id = d.id

Заявката връща комбинираните данни, които се пресичат в състоянието, посочено във вътрешната присъединят на <..>.
В този случай, при условие <таблица_пользователей>.<идентификатор_отдела> трябва да съответства на <таблица_отделов>.<идентификатор>

В резултат на това не е:

- от Александър (Division 6 - не съществува)
- Министерството на финансите (няма потребители)

име идентификатор d_name
-- -------- ---------
1 Владимир Продажби
2 Подкрепа Антон
4 Борис поддръжка
3 Юрий Логистика

Вътрешна присъединят INNER JOIN (синоним JOIN, Вътрешна дума може да се пропусне).

Изберете само данните за съвпадение от присъединените масите.


За да получите данните, които са подходящи за състоянието, в част, трябва да се използва

Външна присъединяване - ВЪНШНА JOIN.

Тези данни връщане асоциация от двете таблици (съвпадение състояние на асоциация) плюс допълват останалите примерни данни от външен маса, който не е подходящ за състоянието, пълнене липсваща стойност NULL данни.

Има два вида на външната връзка ВЪНШНА на присъединяване - лявата външна JOIN и дясната външна JOIN.

Те работят по същия начин, разликата се крие във факта, че в ляво - показва, че "външната" масата ще бъде разположен от лявата страна (в този пример, потребителите таблицата).
ВЪНШНА дума може да се пропусне. Запис НАЛЯВО JOIN идентичен лявата външна JOIN.

SELECT u.id. u.name. d.name AS d_name
От потребителите ф
Лявата външна JOIN отдели D ON u.d_id = d.id

Снабдете се с пълния списък на потребителите и ведомства са свързани.

име идентификатор d_name
-- -------- ---------
1 Владимир Продажби
2 Подкрепа Антон
3 Александър NULL
4 Борис поддръжка
5 Юри Логистика

КЪДЕ d.id е нула

в пробата ще бъде само 3 # Александър, тъй като той не е бил назначен отдел.

Фиг. Лявата външна присъединят филтриране от областта


Дясната външна JOIN се връща в списъка на отдели (вдясно маса) и картирани потребители.

SELECT u.id. u.name. d.name AS d_name
От потребителите ф
Дясната външна JOIN отдели D ON u.d_id = d.id

име идентификатор d_name
-- -------- ---------
1 Владимир Продажби
2 Подкрепа Антон
4 Борис поддръжка
NULL NULL финансите
5 Юри Логистика

Освен това можете да филтрирате данните, проверка за NULL.

SELECT d.id. d.name
От потребителите ф
Дясната външна JOIN отдели D ON u.d_id = d.id
КЪДЕ u.id е нула

В нашия пример се посочва, ако u.id е нула, ние ще изберем отделите, които не са регистрирани потребители. (# 3 финансите)


Всички примери които можете да тествате тук:

FULL JOIN връща `obedinenie` асоциации лявата и дясната маси, комбиниране на резултатите от две запитвания.

CROSS JOIN връща пресичат (декартови) комбиниране на двете плочи. Резултатът ще бъде проба от всички записи на първата таблица, свързани с всеки ред от втората таблица. Важното е, че кръстът не е необходимо да се определи състоянието на присъединят.

Дублиращи редове, използвайки JOIN

При използване на комбинация начинаещи често забравяме, че в резултат на пробата може да съдържа дублирани данни!
Ако имате нужда от един запис, да направи съюза с подзаявка

SELECT t1. *. t2. * От left_table t1 ляво се присъединят # 40; изберете * от right_table където some_column = 1 граница 1 # 41; t2 ON t1.id = t2.join_id







Пробата на една и съща маса в продължение на няколко условия.

Помислете за задача Yandex:

Има маса на стоки.

Създаване на таблица `те _ goods` # 40;
`Id` Int # 40; 11 # 41; неподписан NOT NULL auto_increment.
`Name` VARCHAR # 40; 64 # 41; NOT NULL.
първичен ключ # 40; `id` # 41;
# 41; ДВИГАТЕЛ = InnoDB DEFAULT CHARSET = utf8;
вмъкнете в ya_goods ценности # 40; 1. "Ябълки" # 41. # 40; 2. "ябълки" # 41. # 40; 3. "круша" # 41. # 40; 4. "ябълки" # 41. # 40; 5. "портокали" # 41. # 40; 6. "круша" # 41; ;

Той съдържа следните стойности.

`Id`` name`
1 Ябълките
2 ябълки
3 круши
4 Ябълките
5 Портокали
6 круши

Напишете заявка, която избира уникален чифт `id` стоки с identical` name`, например:

При решаването на проблема да се отбележи, че двойката (х, у) и (Y, X) - са идентични.

SELECT g1.id ID1. g2.id ID2
-- CONCAT ( "(" ПОНЕ (g1.id, g2.id) ',', ГОЛЯМАТА (g1.id, g2.id) ")") на ред
ОТ ya_goods g1
INNER JOIN ya_goods g2 ON g1.name = g2.name
КЪДЕ g1.id <> g2.id
ГРУПА ОТ ПОНЕ # 40; g1.id. g2.id # 41. ГОЛЯМОТО # 40; g1.id. g2.id # 41;
ORDER BY g1.id;

-- или без групи (по-бързо)

SELECT DISTINCT CONCAT # 40; "(". ПОНЕ # 40; g1.id. g2.id # 41. ''. ГОЛЯМОТО # 40; g1.id. g2.id # 41. ")" # 41; ред
ОТ ya_goods g1
INNER JOIN ya_goods g2 ON g1.name = g2.name
КЪДЕ g1.id <> g2.id

Комбинирайте маса ya_goods на една и съща област, `name`, ги групирате по уникален identifikatoram и да получите резултат.


Множество мулти присъединят съюз

Полезно за нас, ако искате да изберете повече от една стойност от масата в продължение на няколко условия.

Пример: набор от опции (тегло, обем) на стоки.
Продукти в таблицата с продукти, опции - Таблица product_options, опционни ценности - Таблица product2options
Необходимо е: да филтрирате продуктите по дата и наличните възможности

Създаване на таблица `продукти с # 40;
`Id` Int # 40; 11 # 41.
`Звание VARCHAR # 40; 255 # 41.
`Създадена _ at` дата и час
# 41;

Създаване на таблица `_ продукт options` # 40;
`Id` Int # 40; 11 # 41.
`Name` VARCHAR # 40; 255 # 41;
# 41;

Създаване на таблица `product2options` # 40;
`_ Продукта id` Int # 40; 11 # 41.
`_ Вариант id` Int # 40; 11 # 41.
`Допустима стойност Int # 40; 11 # 41;
# 41;

INSERT INTO `_ продукт options` # 40; `Id`. `name` # 41; СТОЙНОСТИ
# 40; 11. "тежест" # 41.
# 40; 12. "Обем" # 41; ;

INSERT INTO `product2options` # 40; `_ Продукта id`. `Вариант _ id`. `допустима стойност # 41; СТОЙНОСТИ
# 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; ;

Просто списъка с опции по отношение на под-заявка / dzhoine чрез и / или не работи,
необходимо да се извърши присъединяването маси опции, равен на броя на същите тези опции (имаме - 2: обем и тегло)

SELECT стр. *. po1.name "Р1". p2o1. стойност. po2.name "Р2". p2o2. стойност

ОТ продукти р

INNER JOIN product2options p2o1 ON p.id = p2o1.product_id
INNER JOIN product_options PO1 ON po1.id = p2o1.option_id

INNER JOIN product2options p2o2 ON p.id = p2o2.product_id
INNER JOIN product_options ВП2 ON po2.id = p2o2.option_id

Комбинациите могат да бъдат използвани във връзка с актуализацията.
Например, имаме къщи маса (номер, заглавие, област). Вие трябва да изберете заглавието, ако тя отговаря на редица m2` `Сменете площ Фийлд, ако тя е по-малко. защото в MySQL otstutsutstvuet подкрепа за регулярни изрази, имате нужда от малко pokoldovat да намерите и SUBSTR.
В подзаявка изберете данните, които представляват интерес, и в заключителния етап на данните се актуализират с подходящите критерии (p5> площ).

UPDATE къщи база
INNER JOIN # 40;
-- Antaris 1594 m2 офис под наем в размер на 12,700 рубли. m2 / година -> 1594
SELECT
идентификатор.
@baseString: = заглавното съединение.
@areaTitleEnd: = LOCATE # 40; "М2". @baseString # 41; като p2.
@tmpString: = LTRIM # 40; ОБРАТНА # 40; SUBSTR # 40; @baseString. 1. @areaTitleEnd # 41; # 41; # 41; като P3.
@areaTitleBegin: = НАЛЯВО # 40; @tmpString. - 1 + LOCATE # 40; ''. @tmpString # 41; # 41; като P4.
@ Стойност: = CAST # 40; ОБРАТНА # 40; @areaTitleBegin # 41; като неподписан # 41; като p5

ОТ ga_pageviews
КЪДЕ заглавие като "%% m2"
# 41; изчислено ИЗПОЛЗВАНЕ # 40; `id` # 41;
SET база. площ = calc.p5
КЪДЕ база. област

Вземем примера на премахване на дубликати. Има маса tableWithDups (номер, електронна поща). Необходимо е да се премахне границата със същия имейл адрес:

DELETE tableWithDups
ОТ tableWithDups
INNER JOIN # 40;
SELECT MAX # 40; идентификатор # 41; AS lastId. имейл
ОТ tableWithDups
Група чрез имейл
КАТО БРОЙ # 40; * # 41> 1
# 41; dups ЗА dups.email = tableWithDups.email
КЪДЕ tableWithDups.id

Последните два примера не са съвместими с ANSI SQL, но работят в MySQL.

Зад статията са свързани асоциации (както и за някои конкретни теми bazdannyh):
СЕБЕ присъединят, ПЪЛНО КАРТОНЕНА присъединят, CROSS УЧАСТВА (CROSS [КАРТОНЕНА] Прилагане), определена операции съюз [ALL], пресичат, ОСВЕН т.н.

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