Объяснение самосоединений


Я не понимаю необходимости самосоединения. Может кто-нибудь объяснить их мне?

простой пример был бы очень полезен.

12 66

12 ответов:

вы можете просмотреть самосоединение в виде двух одинаковых таблиц. Но в нормализации, нельзя создать две копии таблицы, так что вы просто имитировать наличие двух таблиц с самосоединение.

Предположим, у вас есть две таблицы:

таблица 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

Это довольно часто, когда у вас есть таблица, которая сама ссылается. Пример: таблица сотрудников, в которой каждый сотрудник может иметь менеджера, и вы хотите перечислить всех сотрудников и имя их менеджера.

SELECT e.name, m.name
FROM employees e LEFT OUTER JOIN employees m
ON e.manager = m.id

self join-это объединение таблицы с самой собой.

общий случай использования, когда таблица хранит сущности (записи), которые имеют иерархическую связь между ними. Например, таблица, содержащая информацию о человеке (имя, DOB, адрес...) и включая колонку, в которой указан идентификатор отца (и/или матери). Затем с небольшим запросом, как

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 столбцы с той же таблицей

без возможности для таблицы ссылаться на себя, нам пришлось бы создать столько таблиц для уровней иерархии, количество уровней в иерархии. Но поскольку эта функциональность доступна, вы присоединяете таблицу к себе, и sql обрабатывает ее как две отдельные таблицы, поэтому все хранится красиво в одном месте.

представьте себе таблицу под названием Employee, как описано ниже. У всех сотрудников есть менеджер, который также является сотрудником (возможно, за исключением генерального директора, чей manager_id будет равен null)

Table (Employee): 

int id,
varchar name,
int manager_id

затем вы можете использовать следующий Select, чтобы найти всех сотрудников и их руководителей:

select e1.name, e2.name as ManagerName
from Employee e1, Employee e2 where
where e1.manager_id = e2.id

есть много правильных ответов, но есть вариант, что одинаково правильно. Вы можете поместить свои условия соединения в инструкцию join вместо предложения 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 > Е2.код

преимущество знания обоих сценариев заключается в том, что иногда у вас есть тонна условий WHERE или JOIN, и вы хотите поместить свои условия self 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

помимо ответов, упомянутых выше (которые очень хорошо объяснены), я хотел бы добавить один пример, чтобы можно было легко показать использование Self Join. Предположим, у вас есть таблица с именем CUSTOMERS, которая имеет следующие атрибуты: CustomerID, CustomerName, ContactName, Город, Страна. Теперь вы хотите перечислить всех тех, кто из "того же города" . Вам придется придумать копию этой таблицы, чтобы мы могли присоединиться к ним на основе города. Запрос ниже наглядно покажет, что это такое значит:

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;

один вариант использования-это проверка наличия повторяющихся записей в базе данных.

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

Это эквивалент базы данных связанного списка / дерева, где строка содержит ссылку в некотором качестве на другую строку.

вот объяснение самосоединения в непрофессиональных терминах. Self join-это не другой тип соединения. Если вы поняли другие типы соединений (внутренние, внешние и перекрестные соединения), то self join должен быть прямым. Во внутреннем, внешнем и перекрестном соединениях вы соединяете 2 или более разных таблиц. Однако, в собственной присоединиться к вам присоединиться к той же таблице с itslef. Здесь у нас нет 2 разных таблиц, но мы обрабатываем одну и ту же таблицу как другую таблицу, используя псевдонимы таблиц. Если это все еще не ясно, я рекомендую посмотреть следующие видео на youtube.

самостоятельно к примеру