Types of JOINs - JOIN의 종류들
당신이 데이터베이스를 만들 때, 이는 여러 테이블에 정보를 저장하기 편리했습니다.
물론, 중복을 피하며, 테이블의 유지하기 편리하게 만들며, 그들 사이의 연결을 올바른 방향으로 설립합니다.
실제 프로젝트의 작업은, 당신이 원하는 정보를 테이블에서 얻기 위해서 하나의 테이블 이상을 종종 사용할 겁니다.
이 곳이 JOIN이 필요한 곳 입니다.
이론에서는, SQL의 join은 SQL (Structed Query Language) 지침인데,
검색 조건에 기초해 두 테이블의 레코드를 결합하는 지침입니다.
검색 조건 계산이 참 이라면, 레코드들이 조인 됩니다.
계산 결과 줄들은 두 개의 조인 된 테이블들의 모든 컬럼들로 구성됩니다.
Types of JOINs - 서로 다른 종류의 JOIN들
JOIN
에는, 두 개의 테이블이 존재합니다. : Left Table and Right Table.
Left Table 그리고 Right Table은 JOIN
절에서 지정됩니다.
그리고, 조인의 결과는 오른쪽 테이블의 줄들과 매칭되는 왼쪽 테이블의 모든 줄들을 담을 겁니다.
만약, 오른쪽 테이블에서 어떠한 것도 일치하지 않는다면,
결과는 오른쪽 테이블의 컬럼에 대한 NULL
값과 함께 왼쪽 테이블에서 일치하지 않는 줄들을 포함하게 됩니다.
해석 :
왼쪽과 오른쪽 테이블이 존재한다 가정 할 때,
Left Join을 사용한다 하면,
왼쪽 테이블의 모든 결과를 출력하되,오른쪽 테이블과 매칭되지 않으면 NULL 로 된다는 뜻 입니다.
SQL 에는 서로 다른 종류의 JOIN이 존재합니다 :
[INNER] JOIN :
왼쪽 테이블의 각각의 레코드에서 오른쪽 테이블과 병합 조건을 만족하는 모든 레코드들을 원본 레코드와 병합하고,
결과 테이블에 추가합니다.
오른쪽 테이블에서 어떠한 레코드들도 매칭되지 않는다면, 원본 레코드 또한 결과 테이블에 추가되지 않습니다.
(INNER
키워드를 사용하는 것은 선택입니다.)
LEFT/RIGHT JOIN :
Right/Left 테이블의 값과 매칭되는 Left/Right 테이블의 모든 레코드들을 반환합니다.
이 문장만 보면 매칭되는 레코드들만 반환할 것 같이 보이지만, 모든 레코드를 반환하며,
일치하지 않으면 NULL 값을 집어넣는다.
만약 한 테이블의 다른 테이블과 일치되지 않는 몇몇 레코드들을 가지고 있다면,
오른쪽 테이블의 출력결과로 해당되는 컬럼들을 NULL 로 할당합니다.
FULL [OUTER] JOIN :
왼쪽, 혹은 오른쪽 테이블에서 일치하는 것이 있다면, 모든 레코드들을 반환합니다.
매칭되지 않은 레코드들은 NULL 을 할당받습니다.
(OUTER
키워드 사용은 선택입니다.)
위의 JOIN 정리
INNER JOIN
Left Table | match | Right Table |
---|---|---|
Select |
LEFT JOIN
Left Table | match | Right Table |
---|---|---|
select | Select |
RIGHT JOIN
Left Table | match | Right Table |
---|---|---|
Select | select |
FULL OUTER JOIN
Left Table | match | Right Table |
---|---|---|
select | Select | select |
CROSS JOIN :
왼쪽 테이블의 모든 레코드들과 오른쪽 테이블의 모든 레코드들을 크로스 조인 합니다. (밑에 예시 존재)
CROSS JOIN에서는 두 테이블 간 어떤 조건으로 조인 하는지 지정하지 않습니다.
flowchart LR
A('A')
B('B')
C('C')
1('1')
2('2')
3('3')
subgraph table1
subgraph column1
subgraph id1
direction LR
1
2
3
end
end
end
subgraph table2
subgraph column2
subgraph id2
direction LR
A
B
C
end
end
end
1 --> A
1 --> B
1 --> C
2 --> A
2 --> B
2 --> C
3 --> A
3 --> B
3 --> C
class id1,id2 classID;
class 1,2,3,A,B,C classCell;
classDef classID padding:2rem;
classDef classCell padding:2rem;
mermaid
기능으로 직선 그래프를 그려보려고 했으나, 생각보다 깔끔하게 그려지지 않았어요..
1, 2, 3 모두 A, B, C와 전부 연결 되어 있는 뜻입니다. 밑의 표를 보면 더 선명하게 이해 될 겁니다.
Result:
id1 | id2 |
---|---|
1 | A |
1 | B |
1 | C |
2 | A |
2 | B |
2 | C |
3 | A |
3 | B |
3 | C |
따라서, table1의 id1
은 idA
, idB
, idC
를 조인하며,
id2
, id3
또한 똑같이 조인합니다.
INNER JOIN - 내부 조인
한 번 서로 다른 타입의 조인이 작업하는 걸 봅시다.
밑의 테이블 character
, pet
, universe
를 고려 해 봅시다.
character 테이블은 여러 컬럼을 가지고 있습니다.
character_id (INT)
character_name (VARCHAR(30))
universe_id (INT)
character_id | character_name | universe_id |
---|---|---|
1 | Harry Potter | 1 |
2 | Severus Snape | 1 |
3 | Voldemort | 1 |
4 | Hermione Granger | 1 |
5 | Tyrion Lannister | 2 |
6 | Daenerys Targaryen | 2 |
7 | Argus Filch | 1 |
pet 테이블은 이러한 컬럼을 가지고 있습니다.
character_id (INT)
pet_species (VARCHAR(50))
character_id | pet_species |
---|---|
1 | owl |
3 | snake |
4 | cat |
6 | dragon "Drogo" |
6 | dragon "Rhaegal" |
6 | dragon "Viserion" |
8 | puppy |
9 | unicorn |
universe 테이블은 이러한 컬럼을 가지고 있습니다.
universe_id (INT)
universe_name (VARCHAR(30))
author (VARCHAR(30))
universe_id | universe_name | author |
---|---|---|
1 | Harry Potter | Joanne Rowling |
2 | Game of Thrones | George R. R. Martin |
INNER JOIN
의 일반적인 구문은 이렇습니다. :
SELECT table1.col_name1, table2.col_name2
FROM table1 [AS a]
INNER JOIN table2 [AS b]
ON table1.id = table2.id;
JOIN 조건이 =
와는 다른 것을 수도 있음을 참고하세요.
위 명령어 중 괄호의 뜻은 선택이라는 뜻입니다.
Ordering results of INNER JOIN - INNER JOIN 결과 정렬하기
다시 실용적인 예제로 돌아와서,
당신이 어떤 펫이 어떠한 캐릭터에 속해 있는지 알고 싶다고 가정하겠습니다.
이를 수행하기 위해서, 우리는 밑의 쿼리를 실행해야 합니다 :
SELECT character_name, pet_species
FROM character
INNER JOIN pet
ON character.character_id = pet.character_id
ORDER BY character.character_name;
이 쿼리의 결과 테이블은 밑과 같습니다 :
character_name | pet_species |
---|---|
Daenerys Targaryen | dragon "Drogo" |
Daenerys Targaryen | dragon "Rhaegal" |
Daenerys Targaryen | dragon "Viserion" |
Harry Potter | owl |
Hermione Granger | cat |
Voldemort | snake |
하지만, 당신이 볼 수 있다시피, 모든 캐릭터가 결과에 포함되지 않았습니다.
이렇게 된 이유는, 왼쪽 테이블의 몇 개의 레코드가 오른쪽 테이블과 매칭되지 않았기 때문입니다.
이 예제의 모든 캐릭터가 애완동물을 가지진 않습니다.
이 문제를 해결하고, 모든 캐릭터를 결과에 포함시키기 위해, LEFT JOIN
을 사용합니다.
두 테이블에서 character_id
가 일치하는 줄들의 정보를 결합 해 왔습니다.
SELECT character_name, pet_species
FROM character
LEFT JOIN pet
ON character.character_id = pet.character_id
ORDER BY character.character_name;
Result :
character_name | pet_species |
---|---|
Argus Filch | NULL |
Daenerys Targaryen | dragon "Drogo" |
Daenerys Targaryen | dragon "Rhaegal" |
Daenerys Targaryen | dragon "Viserion" |
Harry Potter | owl |
Hermione Granger | cat |
Severus Snape | NULL |
Tyrion Lannister | NULL |
Voldemort | snake |
우리는 그저 두 개의 테이블로 작업해 왔지만, 그 이상의 다중 테이블을 같이 조인 할 수도 있습니다.
예를 들어, 우리가 캐릭터들이 어떤 세계에서 왔는지 알고 싶은 경우가 존재합니다.
볼 수 있다시피, 오른쪽 테이블과 매치가 되지 않는 값들은 NULL
값이 할당됩니다.
SELECT c.character_name, p.pet_species, u.universe_name
FROM universe AS u
LEFT JOIN character AS c
ON u.universe_id = c.universe_id
LEFT JOIN pet AS p
ON p.character_id = c.character_id
;
Result :
character_name | pet_species | universe_name |
---|---|---|
Harry Potter | owl | Harry Potter |
Severus Snape | NULL | Harry Potter |
Voldemort | snake | Harry Potter |
Hermione Granger | cat | Harry Potter |
Tyrion Lannister | NULL | Game of Thrones |
Daenerys Targaryen | dragon "Drogo" | Game of Thrones |
Daenerys Targaryen | dragon "Rhaegal" | Game of Thrones |
Daenerys Targaryen | dragon "Viserion | Game of Thrones |
Argus Filch | NULL | Harry Potter |
CROSS JOINs 에 대해 이해하는 것이 유용 할 겁니다.
체스 대회가 있는데, 이 대회의 주최자가 모든 참가자들을 짝을 지을 필요가 있다고 생각 해 봅시다.
또한, 컬럼을 선택 할 때, table_name1.col_name
과 같이 필수적으로 쓸 필요는 없다는 걸 참고하세요.
계산에 사용될 모든 테이블을 아울러 유일한 컬럼 이름이라면, 생략 할 수 있습니다.
하지만, 여전히 표기하는 것을 추천하는데, 이는 다중 테이블을 가지고 있을 때, 컬럼의 이름이 모호해지기 때문입니다.
우리는 테이블 이름에 대해 별칭을 사용할 수 있다는 점을 참고하세요.
SQL alias (별칭) 은 테이블 혹은 테이블 내부의 컬럼에 임시적인 이름을 주는 데 사용한다는 것을 기억하세요.
예를 들어, SELECT person_name AS name
이 있습니다.
이 기능은 테이블들이 긴 이름을 가지고 있을 때, 엄청나게 도움이 됩니다.
여기서 말하건대, 테이블들을 연결하고 싶을 때, JOIN
을 꼭 사용 할 필요가 없다는 말을 할 수 있습니다.
당신은 WHERE
조건절을 사용해야 같은 결과를 얻을 수 있습니다.
가능하다면, 밑의 글을 고려 해 보세요.
밑의 쿼리는 위의 쿼리와 동일한 결과를 가져다 줍니다. :
SELECT table1.col_name1, table2.col_name2
FROM table1 [AS a], table2 [AS b]
WHERE table1.id = table2.id;
쿼리 내부의 []
의미는 선택적으로 기입할 수 있다는 뜻입니다.
Conclusion - 결론
여러 개의 테이블을 조인하기 위해서, 밑의 템플릿을 따르세요 :
SELECT val1 [AS name1], ..., valN [AS nameN]
FROM table1
[type_of_join] JOIN table2
ON table1.col_name_table1 = table2.col_name_table2
[type_of_join] JOIN table3
ON table2.col_name_table2 = table3.col_name_table3;
축하합니다! 이제 당신은 다중 테이블을 쿼리하는 법을 알게 되었습니다.
이제 연습해 보지 않겠습니까?
'Hyperskill - 컴퓨터 CS 및 영어 독해 > Introducing to SQL' 카테고리의 다른 글
Updating selected rows - 선택된 줄들 업데이트하기 (1) | 2024.04.25 |
---|---|
Basic UPDATE statement - 기초적인 UPDATE 문법 (0) | 2024.04.25 |
Results ordering - 결과 정렬하기 (1) | 2024.04.22 |
FOREIGN KEY constraint - 외래 키 제약 조건 (2) | 2024.04.21 |
PRIMARY KEY constraint - 기본 키 제약 조건 (0) | 2024.04.20 |