셀프 조인 설명


84

셀프 조인의 필요성을 이해하지 못합니다. 누군가 나에게 설명해 주시겠습니까?

간단한 예가 매우 도움이 될 것입니다.

답변:


95

셀프 조인을 두 개의 동일한 테이블로 볼 수 있습니다. 그러나 정규화에서는 테이블의 복사본을 두 개 만들 수 없으므로 셀프 조인이있는 두 개의 테이블이있는 것을 시뮬레이션하면됩니다.

두 개의 테이블이 있다고 가정합니다.

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

1
이 예에서는 누가 보스인지 알 수 없습니다. 특급은 좋고 이해하기 쉽습니다.
MAC

2
left join상사가없는 직원 (또는 상사)을 제외하지 않는 편이 낫다고 생각합니다. 최고 개!
Rockin4Life33

22

자신을 참조하는 테이블이있는 경우 매우 일반적입니다. 예 : 모든 직원이 관리자를 가질 수 있고 모든 직원과 해당 관리자의 이름을 나열하려는 직원 테이블.

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

18

자체 조인은 자신과 테이블의 조인입니다.

일반적인 사용 사례는 테이블이 항목 (레코드)간에 계층 적 관계가있는 항목을 저장하는 경우입니다 . 예를 들어 개인 정보 (이름, 생년월일, 주소 ...)를 포함하고 아버지 (및 / 또는 어머니)의 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

동일한 쿼리에서 자녀와 아버지 (및 어머니, 두 번째 셀프 조인 등, 심지어 조부모 등)에 대한 정보를 얻을 수 있습니다.


5

다음 users과 같이 설정된 테이블이 있다고 가정 해 보겠습니다 .

  • 사용자 ID
  • 사용자 이름
  • 사용자의 관리자 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

4

테이블이 자기 참조 인 경우 유용합니다. 예를 들어 페이지 테이블의 경우 각 페이지에 nextprevious링크 가있을 수 있습니다 . 이는 동일한 테이블에있는 다른 페이지의 ID입니다. 어떤 시점에서 연속 된 페이지의 세 개를 얻으려면 동일한 테이블의 열 을 사용하여 nextprevious열에 대해 두 개의 자체 조인을 수행합니다 id.


4

Employee아래에 설명 된 테이블이 있다고 상상해보십시오 . 모든 직원에게는 직원이기도 한 관리자가 있습니다 (Manager_id가 null 인 CEO 제외)

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

4

테이블이 자신을 참조하는 기능이 없으면 계층 구조의 계층 수만큼 계층 수준에 대한 테이블을 만들어야합니다. 그러나 해당 기능을 사용할 수 있으므로 테이블을 자체에 조인하고 SQL은이를 두 개의 개별 테이블로 취급하므로 모든 것이 한 곳에 잘 저장됩니다.


그러나 이제 당신은 (희망적으로) 자기 참조를 사용할 수 없다면 어떤 일이 일어날 지 이해합니다.
Eugene

4

위에서 언급 한 답변 (매우 잘 설명되어 있음) 외에도 Self Join의 사용을 쉽게 보여줄 수 있도록 한 가지 예를 추가하고 싶습니다. CustomerID, CustomerName, ContactName, City, Country 속성이있는 CUSTOMERS라는 테이블이 있다고 가정합니다. 이제 "같은 도시"에서 온 사람들을 모두 나열하려고합니다. 이 테이블의 복제본을 생각해야 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;

3
+1이 답변은 SO에 대한 답변이 "자체 조인 사용"인 SQL 질문이 너무 많기 때문에 매우 중요합니다. 사람들은 명시 적 (계층 적) 자기 참조가 없을 때 보지 못하는 경향이 있습니다.
JimmyB

1
tho 이것은 w3schools의 복사 파스타입니다.
George K

3

여기에는 많은 정답이 있지만 똑같이 올바른 변형이 있습니다. 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

1
흠, 강아지에서는 왜 "같음"대신 "보다 큼"에 가입합니까?
Marcel

1
안녕하세요. 일부 예제에서는 "FROM xxx, yyy WHERE"및 다른 "FROM xxx JOIN yyy WHERE"를 사용하는 것을 보았습니다. 차이점을 설명해 주시겠습니까?
skan

@Skan 정말 좋은 질문입니다. 짧은 대답은 이것이 오래된 속기 방법이며 더 이상 사용되지 않을 것이라는 것입니다. 10 년 이상 전에 학교에서 사용했지만 실제로는 거의 볼 수 없습니다. 내가 찾을 수있는 가장 간결한 설명은 다음과 같습니다. bidn.com/blogs/KathiKellenberger/sql-server/2875/…
BClaydon

1

한 가지 사용 사례는 데이터베이스에서 중복 레코드를 확인하는 것입니다.

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

GROUP BY 및 HAVING 절을 사용하여 중복을 찾는 것이 훨씬 빠릅니다. SELECT name, email, COUNT ( ) FROM My_Bookings GROUP BY name, date HAVING COUNT ( )> 1
George K

@GeorgeK 맞습니다. 나는 이것이 완전 평등이 아니라 퍼지 일치 (TRIM (LOWER (Name))에 의한 그룹화를 넘어서)에만 필요하다고 생각합니다.
Molossus Spondee

1

셀프 조인은 테이블의 데이터를 자체적으로 평가해야 할 때 유용합니다. 즉, 동일한 테이블의 행을 상호 연결합니다.

Syntax: SELECT * FROM TABLE t1, TABLE t2 WHERE t1.columnName = t2.columnName

예를 들어 초기 지정이 현재 지정과 동일한 직원의 이름을 찾으려고합니다. 다음과 같은 방법으로 self join을 사용하여 해결할 수 있습니다.

SELECT NAME FROM Employee e1, Employee e2 WHERE e1.intialDesignationId = e2.currentDesignationId

0

연결된 목록 / 트리와 동일한 데이터베이스로, 행에는 다른 행에 대한 일부 용량의 참조가 포함됩니다.


실제로, 둘 이상의 행이 "부모"를 참조 할 수 있다는 점을 감안할 때 직원-> 관리자의 자주 인용되는 예와 같이 트리가 될 수도 있습니다.
NVRAM

나는 단순한 비유를 시도하고 있었지만, 그렇습니다. 나무도 작동 할 수 있습니다.
Unsliced

-4

다음은 평신도 용어로 자기 결합에 대한 설명입니다. 자체 조인은 다른 유형의 조인이 아닙니다. 다른 유형의 조인 (내부, 외부 및 교차 조인)을 이해했다면 자체 조인은 간단해야합니다. INNER, OUTER 및 CROSS JOINS에서 2 개 이상의 서로 다른 테이블을 조인합니다. 그러나 셀프 조인에서는 itslef와 동일한 테이블을 조인합니다. 여기에는 2 개의 다른 테이블이 없지만 테이블 별칭을 사용하여 동일한 테이블을 다른 테이블로 취급합니다. 이것이 여전히 명확하지 않다면 다음 유튜브 비디오를 보는 것이 좋습니다.

예를 들어 셀프 조인

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.