Причини за OUTER JOIN
Между другото, помните ли, когато обединихме нашите електронни таблици и задачите ни за почистване на офиси изчезнаха, защото все още нямаше чистач?
Ако изпълните заявка като тази:
SELECT * FROM task
Тогава получаваме този резултат:
document за самоличност | Emploee_id | име | краен срок |
---|---|---|---|
1 | 1 | Коригиране на грешка във фронтенда | 2022-06-01 |
2 | 2 | Коригиране на грешка в бекенда | 2022-06-15 |
3 | 5 | Купи кафе | 2022-07-01 |
4 | 5 | Купи кафе | 2022-08-01 |
5 | 5 | Ще купи кафе | 2022-09-01 |
6 | (НУЛА) | Почистете офиса | (НУЛА) |
7 | 4 | Наслаждавай се на живота | (НУЛА) |
8 | 6 | Наслаждавай се на живота | (НУЛА) |
Задачата „Изчистване на офиса“ изчезва, ако се опитаме да свържем tableта на задачите с tableта на служителите чрез employee_id.
За да се реши този проблем, към оператора JOIN са добавени различни модификатори, които позволяват такива осиротели редове да се съхраняват без двойка в друга table.
Нека ви напомня за класическата форма на оператора JOIN:
table 1 JOIN table 2 ON
condition
Можем да кажем на SQL Server да се увери, че всички данни от лявата table (table1) присъстват в обединената table. Дори и да няма чифт за тях в правилната маса. За да направите това, просто трябва да напишете:
table 1 LEFT JOIN table 2 ON condition
Ако искате обединената table да има всички редове от дясната table , тогава трябва да напишете:
table 1 RIGHT JOIN table 2 ON
condition
Нека напишем заявка, която ще комбинира всички задачи и служители, така че задачите без изпълнител да не се губят. За да направите това, напишете заявка:
SELECT * FROM employee e RIGHT JOIN task t ON e.id = t.emploee_id
И резултатът от тази заявка:
document за самоличност | име | професия | заплата | възраст | дата на присъединяване | document за самоличност | Emploee_id | име |
---|---|---|---|---|---|---|---|---|
1 | Ivanов Ivan | Програмист | 100 000 | 25 | 2012-06-30 | 1 | 1 | Коригиране на грешка във фронтенда |
2 | Peterов Петър | Програмист | 80 000 | 23 | 2013-08-12 | 2 | 2 | Коригиране на грешка в бекенда |
4 | Рабинович Мойша | Директор | 200 000 | 35 | 2015-05-12 | 7 | 4 | Наслаждавай се на живота |
5 | Кириенко Анастасия | Офис мениджър | 40 000 | 25 | 2015-10-10 | 3 | 5 | Купи кафе |
5 | Кириенко Анастасия | Офис мениджър | 40 000 | 25 | 2015-10-10 | 4 | 5 | Купи кафе |
5 | Кириенко Анастасия | Офис мениджър | 40 000 | 25 | 2015-10-10 | 5 | 5 | Купи кафе |
6 | Васка | котка | 1000 | 3 | 2018-11-11 | 8 | 6 | Наслаждавай се на живота |
(НУЛА) | (НУЛА) | (НУЛА) | (НУЛА) | (НУЛА) | (НУЛА) | 6 | (НУЛА) | Почистете офиса |
Друг ред е добавен към нашата table и интересното е, че в него има много NULL стойности. Всички данни, взети от tableта на служителите, се показват като NULL, тъй като нямаше изпълнител от tableта на служителите за задачата „Почистване на офиса“.
JOIN типове
Има общо 4 вида JOIN. Те са представени в tableта по-долу:
Кратко вписване | дълго влизане | Обяснение | |
---|---|---|---|
1 | ПРИСЪЕДИНЯВАНЕ | ВЪТРЕШНО СЪЕДИНЕНИЕ | Само записи, които са в таблици A и B |
2 | ЛЯВО ПРИСЪЕДИНЯВАНЕ | ЛЯВО ВЪНШНО СЪЕДИНЕНИЕ | Всички редове без двойка от table А трябва да бъдат |
3 | ДЯСНО ПРИСЪЕДИНЕТЕ | ДЯСНО ВЪНШНО СЪЕДИНЕНИЕ | Всички редове без двойка от table B трябва да бъдат |
4 | ВЪНШНО СЪЕДИНЕНИЕ | ПЪЛНО ВЪНШНО СЪЕДИНЕНИЕ | Всички редове от базови двойки от таблици A и B трябва да бъдат |
За простота, ако представяме таблиците като набори, тогава JOIN може да се покаже като картина:
![](https://cdn.codegym.cc/images/article/66aba568-a02a-45e0-9939-6beebbb190ed/512.jpeg)
Set intersection означава, че за една table има съответен запис от друга table, към която препраща.
Въпрос от интервюто
Понякога начинаещите програмисти са бомбардирани с много прост въпрос на интервю. Предвид нашите таблици, тя може да се формулира, Howто следва:
„Напишете заявка, която ще покаже списък на всички служители, за които няма задачи .“ Първо, нека се опитаме да перифразираме малко този въпрос: „Напишете заявка, която ще покаже списък на всички служители от tableта на служителите, за които няма задачи в tableта със задачи .“ Трябва да вземем този комплект:![](https://cdn.codegym.cc/images/article/d3cc4f4a-b340-4b3a-9ae0-3e38eca36bb2/512.jpeg)
Има много начини за решаване на този проблем, но ще започна с най-простия: Първо, можете да свържете нашите таблици с LEFT JOIN и след това да използвате WHERE, за да изключите всички редове, за които липсващите данни са бor подплатени с NULL.
SELECT * FROM employee e LEFT JOIN task t ON e.id = t.emploee_id
WHERE t.id IS NULL
И резултатът от тази заявка:
document за самоличност | име | професия | заплата | възраст | дата на присъединяване | document за самоличност | Emploee_id | име |
---|---|---|---|---|---|---|---|---|
3 | Ivanов Сергей | Тестер | 40 000 | тридесет | 2014-01-01 | (НУЛА) | (НУЛА) | (НУЛА) |
Единственият недостатък на това решение е, че тук редовете в tableта съдържат NULL и по condition трябва да изведем списък със служители.
За да направите това, трябва or да изброите необходимите колони на tableта на служителите в SELECT, or ако трябва да ги покажете всички, можете да напишете следната конструкция:
SELECT e.* FROM employee e, task t
Пълната заявка ще изглежда така:
SELECT e.*
FROM employee e RIGHT JOIN task t ON e.id = t.emploee_id
WHERE t.id IS NULL
резултатът от тази заявка:
document за самоличност | име | професия | заплата | възраст | дата на присъединяване |
---|---|---|---|---|---|
3 | Ivanов Сергей | Тестер | 40 000 | тридесет | 2014-01-01 |
Останалите методи оставяме за домашна работа. Не искам да ви лишавам от удоволствието да ги намерите сами.
GO TO FULL VERSION