Объяснение самосоединений
Я не понимаю необходимости самосоединения. Может кто-нибудь объяснить их мне?
простой пример был бы очень полезен.
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.