본문 바로가기
AI/데이터베이스\SQL

[SQL / postgreSQL] SQL 기초 (AS, UNION, JOIN - INNER JOIN, OUTER JOIN, LEFT JOIN, RIGHT JOIN)

by 까다로운오리 2022. 2. 24.

 

AS

SELECT 열 이름 AS 별칭
FROM 테이블

 

열이나 결과에 별칭을 부여하는 함수이다. 별칭은 제일 마지막에 할당되기 때문에 WHERE연산자나 GROUP  BY 호출 같은 것에서는 별칭을 사용할 수 없다. 원래의 열 이름을 사용해야 한다.

 

 

 

 

 


JOIN?

 

출처 : https://chrisaor.github.io/database/2018/02/16/20JOIN.html

여러 테이블을 하나로 결합하는 함수이다.

 

 

 

INNER JOIN

두 테이블을 모두 충족하는 레코드 세트를 결과로 출력한다.

테이블1
ID_1 이름
1 신짱구
2 김철수
3 이훈이
테이블2
ID_2 이름
1 한유리
2 맹구
3 신짱구

 

INNER JOIN은 두 테이블 모두에 속해있는 행만 조회한다. 집합의 교집합이라고 생각하면 편하다. 두 테이블에서 매칭되는 지점은 신짱구이다.  특정 열을기준으로 두 테이블을 결합해야 하는데, 위 사례에선 '이름'이 되겠다. 이를 코드로 쓰면

 

SELECT * FROM 테이블1
INNER JOIN 테이블2
ON 테이블1.이름 = 테이블2.이름

 

테이블1에서 가져와서 테이블2와 INNER JOIN을 하라는 코드이다. ON뒤에는 INNER JOIN을 수행하기 위해 어떤 열을 참조할지 알려준다. INNER JOIN에서는 테이블1,2를  바꿔도 결과가 같다.

 

위 구문의 결과는 아래와 같다.

RESULTS
ID_1 이름 ID_2 이름
1 신짱구 3 신짱구

 

 

SELECT ID_1, 테이블2.이름, ID_2 FROM 테이블1
INNER JOIN 테이블2
ON 테이블1.이름 = 테이블2.이름
RESULTS
ID_1 이름 ID_2
1 신짱구 3

 

그냥 이름이 아닌 테이블2.이름을 하는 이유는 name은 두 테이블에 모두 존재하는데, 만약 JOIN 뒤에 뭔가를 선택한다면 그 name열을 참조하는 테이블이 어떤 열인지 지정해야한다. 

 

1. INNER JOIN에서 테이블의 순서는 중요하지 않다.

2. INNER JOIN이 아닌 그냥 JOIN은 postgresql은 INNER JOIN으로 인식한다.

 

 

 

OUTER JOIN

1. FULL OUTER JOIN

SELECT * FROM 테이블1
FULL OUTER JOIN 테이블2
ON 테이블1.이름 = 테이블2.이름
테이블1
ID_1 이름
1 신짱구
2 김철수
3 이훈이
테이블2
ID_2 이름
1 한유리
2 맹구
3 신짱구

 

 

를 FULL OUTER JOIN 하면

결과
ID_1 이름 ID_2 이름
1 신짱구 3 신짱구
2 김철수 null null
3 이훈이 null null
null null 1 한유리
null null 2 맹구

다음과 같다. 매치되는 값을 입력한 후 매치되지 않는 값들엔 null을 입력한다. 

 

 

INNER JOIN과 정 반되되는 FULL OUTER JOIN을 한다면 WEHRE문을 추가하여 

 

SELECT * FROM 테이블1
FULL OUTER JOIN 테이블2
ON 테이블1.이름 = 테이블2.이름
WHERE 테이블1.ID_1 IS null OR
테이블2.ID_2 IS null

 

과 같이 코드를 작성할 수 있다.

 

해당 코드의 결과는 다음과 같다.

결과
ID_1 이름 ID_2 이름
2 김철수 null null
3 이훈이 null null
null null 1 한유리
null null 2 맹구

 

 

 

2. LEFT OUTER JOIN

왼쪽 테이블에 있는 레코드 세트를 결과로 출력한다. 오른쪽 테이블에 일치하는 결과가 없으면 그 결과는 null이다.

 

SELECT * FROM 테이블1
LEFT OUTER JOIN 테이블2
ON 테이블1.이름 = 테이블2.이름

 

LEFT OUTER JOIN의 벤다이어그램은 대칭이 아니기 때문에 순서가 매우 중요하다. 어떤것이 왼쪽 테이블이 될것인지 지정하기 때문에 FROM 뒤에 오는 테이블이 LEFT 테이블이 된다.

 

테이블1에서 전부를 선택하고 테이블 B에 LEFT OUTER JOIN을 수행한다고 하면 FROM문에서는 왼쪽 테이블인 테이블1을 먼저 참조한다. 테이블1에서 정보를 가져올때 테이블1에만 해당되는 것도 있고 테이블2에 있는것과 일치하는 것도 있다. 이 두가지 경우를 RETURN하는 것이 LEFT OUTER JOIN이다.

 

위 코드의 결과는 다음과 같다.

결과
ID_1 이름 ID_2 이름
1 신짱구 3 신짱구
2 김철수 null null
3 이훈이 null null

 

 

WHERE문으로 조건을 추가하여 왼쪽 테이블에만 고유한 행을 추가할 수 있는데 테이블 A에 고유한 항목만 구하고 싶다면 다음과 같이 입력하면 된다.

 

SELECT * FROM 테이블1
LEFT OUTER JOIN 테이블2
ON 테이블1.이름 = 테이블2.이름
WHERE 테이블2.ID_2 IS null

 

 

3. RIGHT OUTER JOIN

LEFT JOIN과 같은 개념이지만 테이블이 서로 바뀐다는 점이 다르다.

 

SELECT * FROM 테이블1
RIGHT OUTER JOIN 테이블2
ON 테이블1.이름 = 테이블2.이름

 

테이블 2에만 있거나 테이블2와 테이블1에 모두 있는 행을 반환하고 테이블1에만 있는 것은 반환하지 않는다.

 

SELECT * FROM 테이블1
RIGHT OUTER JOIN 테이블2
ON 테이블1.이름 = 테이블2.이름
WHERE 테이블1.ID_1 IS null

 

테이블2에만 있는 것을 반환한다.

 

 

 


 

UNION

2개이상의 SELECT문의 결과 세트를 결합할 수 있다.  UNION은 JOIN과 다르게 두 결과를 직접 붙일 수 있다.

 

SELECT 열 이름 FROM 테이블1
UNION
SELECT 열 이름 FROM 테이블2

 

바로 위에 결과를 쌓을 수 있도록 열이 일치해야한다. 

 

테이블1
ID 이름
1 신짱구
2 김철수
3 이훈이
테이블2
ID 이름
1 한유리
2 맹구
3 신짱구

을 UNION하면

 

테이블1
ID 이름
1 신짱구
2 김철수
3 이훈이
1 한유리
2 맹구
3 신짱구

가 된다. UNION을 여러번 호출하여 결과를 계속해서 붙일 수 있다.

 

 

 


연습문제

 

1. 캘리포니아에 살고 있는 고객의 이메일은 무엇인가?

SELECT district, email FROM address
INNER JOIN customer
ON address.address_id = customer.customer_id
WHERE district = 'California'

 

2. 닉 월버그가 나오는 모든 영화목록을 구해라

 

내 풀이

SELECT film.title, first_name, last_name
FROM (SELECT film_id, first_name, last_name FROM film_actor
INNER JOIN actor
ON actor.actor_id = film_actor.actor_id
WHERE first_name = 'Nick' and last_name = 'Wahlberg') AS film_table
INNER JOIN film
ON film.film_id = film_table.film_id

 

 

강의 풀이

SELECT title, first_name, last_name
FROM film_actor INNER JOIN actor 
ON film_actor.actor_id = actor.actor_id
INNER JOIN film 
ON film_actor.film_id = film.film_id
WHERE first_name = 'Nick' AND last_name = 'Wahlberg'

 

나는 서브쿼리로 테이블을 만들고 그걸 INNER JOIN을 했는데 복잡하게 그럴 필요 없이.. 계속해서 INNER JOIN으로 합치면 된다!