Я не понимаю потребность в самосоединениях. Кто-то может объяснить их мне?
Простой пример был бы очень полезен.
Вы можете рассматривать самообъединение как две одинаковые таблицы. Но при нормализации вы не можете создать две копии таблицы, поэтому вы просто имитируете наличие двух таблиц с помощью self-join.
Предположим, у вас есть две таблицы:
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 - это соединение таблицы с самой собой.
Обычный случай использования - когда в таблице хранятся сущности (записи), имеющие иерархические отношения между собой. Например, таблица, содержащая информацию о человеке (имя, дата рождения, адрес...) и включающая столбец, в котором указан 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
мы можем получить в одном запросе информацию и о ребенке, и об отце (и о матери, со вторым self join и т.д. и даже о бабушках и дедушках и т.д.).
Они полезны, если ваша таблица ссылается на себя. Например, для таблицы страниц каждая страница может иметь ссылку следующая
и предыдущая
. Это будут идентификаторы других страниц в той же таблице. Если в какой-то момент вы захотите получить тройку следующих друг за другом страниц, вы должны выполнить два самосоединения в следующих
и предыдущих
столбцах с одним и тем же идентификатором таблицы
. ] столбец.
Без возможности для таблицы ссылаться на саму себя, нам пришлось бы создать столько таблиц для уровней иерархии, сколько слоев в иерархии. Но поскольку эта функциональность доступна, вы присоединяете таблицу к самой себе, и sql рассматривает ее как две отдельные таблицы, так что все хранится в одном месте.
Представьте себе таблицу с именем 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
Допустим, у вас есть таблица пользователей
, настроенная следующим образом:
В этой ситуации, если вы хотите получить информацию о пользователе и информацию о менеджере в одном запросе, вы можете сделать это:
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
Это эквивалент связанного списка / дерева в базе данных, где строка в некоторой степени содержит ссылку на другую строку.