Я не понимаю необходимости присоединения к себе. Может кто-нибудь объяснить мне их?
Был бы очень полезен простой пример.
Я не понимаю необходимости присоединения к себе. Может кто-нибудь объяснить мне их?
Был бы очень полезен простой пример.
Ответы:
Вы можете рассматривать самосоединение как две идентичные таблицы. Но при нормализации вы не можете создать две копии таблицы, поэтому вы просто имитируете две таблицы с самосоединением.
Предположим, у вас есть две таблицы:
emp1
Id Name Boss_id
1 ABC 3
2 DEF 1
3 XYZ 2
emp2
Id Name Boss_id
1 ABC 3
2 DEF 1
3 XYZ 2
Теперь, если вы хотите получить имя каждого сотрудника с именами его или ее начальника:
select c1.Name , c2.Name As Boss
from emp1 c1
inner join emp2 c2 on c1.Boss_id = c2.Id
Будет выведена следующая таблица:
Name Boss
ABC XYZ
DEF ABC
XYZ DEF
left join
Я думаю, было бы лучше не упускать из виду сотрудника (или начальника), у которого нет начальника; лучшая собака!
Довольно часто у вас есть таблица, которая ссылается на себя. Пример: таблица сотрудников, где у каждого сотрудника может быть менеджер, и вы хотите перечислить всех сотрудников и имя их руководителя.
SELECT e.name, m.name
FROM employees e LEFT OUTER JOIN employees m
ON e.manager = m.id
Самосоединение - это соединение таблицы с самим собой.
Обычно в таблице хранятся объекты (записи), между которыми существует иерархическая связь . Например, таблица, содержащая информацию о человеке (имя, дата рождения, адрес ...) и включающая столбец, в который включен идентификатор отца (и / или матери). Затем с небольшим запросом, например
SELECT Child.ID, Child.Name, Child.PhoneNumber, Father.Name, Father.PhoneNumber
FROM myTableOfPersons As Child
LEFT OUTER JOIN myTableOfPersons As Father ON Child.FatherId = Father.ID
WHERE Child.City = 'Chicago' -- Or some other condition or none
мы можем получить информацию как о ребенке, так и об отце (и матери, со вторым самосоединением и т. д., и даже о бабушках и т. д.) в одном запросе.
Допустим, у вас есть стол users
, настроенный так:
В этой ситуации, если вы хотите , чтобы вытащить как информацию пользователя и информации менеджера в одном запросе, вы можете сделать это:
SELECT users.user_id, users.user_name, managers.user_id AS manager_id, managers.user_name AS manager_name INNER JOIN users AS manager ON users.manager_id=manager.user_id
Они полезны, если ваша таблица является самодостаточной. Например, для таблицы страниц, каждая страница может иметь next
и previous
ссылку. Это будут идентификаторы других страниц в той же таблице. Если в какой-то момент вы захотите получить тройку последовательных страниц, вы должны выполнить два самосоединения по столбцам и с одним next
и previous
тем же id
столбцом таблицы .
Представьте себе таблицу с Employee
именем, описанным ниже. У всех сотрудников есть менеджер, который также является сотрудником (возможно, за исключением генерального директора, у которого manager_id будет null)
Table (Employee):
int id,
varchar name,
int manager_id
Затем вы можете использовать следующий выбор, чтобы найти всех сотрудников и их менеджеров:
select e1.name, e2.name as ManagerName
from Employee e1, Employee e2 where
where e1.manager_id = e2.id
Если бы таблица не могла ссылаться на себя, нам пришлось бы создать столько таблиц для уровней иерархии, сколько слоев в иерархии. Но поскольку эта функция доступна, вы присоединяете таблицу к себе, и sql обрабатывает ее как две отдельные таблицы, поэтому все хранится в одном месте.
Помимо упомянутых выше ответов (которые очень хорошо объяснены), я хотел бы добавить один пример, чтобы можно было легко продемонстрировать использование Self Join. Предположим, у вас есть таблица с именем CUSTOMERS со следующими атрибутами: CustomerID, CustomerName, ContactName, City, Country. Теперь вы хотите перечислить всех, кто из «одного города». Вам нужно будет придумать реплику этой таблицы, чтобы мы могли присоединиться к ним на основе CITY. Приведенный ниже запрос ясно покажет, что это означает:
SELECT A.CustomerName AS CustomerName1, B.CustomerName AS CustomerName2,
A.City
FROM Customers A, Customers B
WHERE A.CustomerID <> B.CustomerID
AND A.City = B.City
ORDER BY A.City;
Здесь есть много правильных ответов, но есть и вариант, который также верен. Вы можете поместить свои условия соединения в оператор соединения вместо предложения WHERE.
SELECT e1.emp_id AS 'Emp_ID'
, e1.emp_name AS 'Emp_Name'
, e2.emp_id AS 'Manager_ID'
, e2.emp_name AS 'Manager_Name'
FROM Employee e1 RIGHT JOIN Employee e2 ON e1.emp_id = e2.emp_id
Имейте в виду, что иногда вам нужно, чтобы e1.manager_id> e2.id
Преимущество знания обоих сценариев заключается в том, что иногда у вас есть масса условий WHERE или JOIN, и вы хотите поместить свои условия самостоятельного соединения в другое предложение, чтобы ваш код был читабельным.
Никто не обращал внимания на то, что происходит, когда у Сотрудника нет менеджера. А? Они не входят в набор результатов. Что, если вы хотите включить сотрудников, у которых нет менеджеров, но не хотите, чтобы возвращались неправильные комбинации?
Попробуйте этого щенка;
SELECT e1.emp_id AS 'Emp_ID'
, e1.emp_name AS 'Emp_Name'
, e2.emp_id AS 'Manager_ID'
, e2.emp_name AS 'Manager_Name'
FROM Employee e1 LEFT JOIN Employee e2
ON e1.emp_id = e2.emp_id
AND e1.emp_name = e2.emp_name
AND e1.every_other_matching_column = e2.every_other_matching_column
Один из вариантов использования - проверка дублирующихся записей в базе данных.
SELECT A.Id FROM My_Bookings A, My_Bookings B
WHERE A.Name = B.Name
AND A.Date = B.Date
AND A.Id != B.Id
Самосоединение полезно, когда вам нужно оценить данные таблицы с самой собой. Это означает, что он сопоставит строки из одной таблицы.
Syntax: SELECT * FROM TABLE t1, TABLE t2 WHERE t1.columnName = t2.columnName
Например, мы хотим найти имена сотрудников, чье начальное назначение совпадает с текущим назначением. Мы можем решить эту проблему с помощью самостоятельного соединения следующим образом.
SELECT NAME FROM Employee e1, Employee e2 WHERE e1.intialDesignationId = e2.currentDesignationId
Это эквивалент базы данных связанного списка / дерева, где строка в некоторой степени содержит ссылку на другую строку.
Вот объяснение самостоятельного присоединения в терминах непрофессионала. Самостоятельное соединение - это не другой тип соединения. Если вы знакомы с другими типами объединений (внутреннее, внешнее и перекрестное), тогда самостоятельное объединение должно быть прямым. В INNER, OUTER и CROSS JOINS вы объединяете 2 или более разных таблиц. Однако при самостоятельном присоединении вы присоединяетесь к одному столу с itslef. Здесь у нас нет двух разных таблиц, но мы обрабатываем одну и ту же таблицу как другую, используя псевдонимы таблиц. Если это все еще не ясно, я бы порекомендовал посмотреть следующие видео на YouTube.