본문 바로가기
개발일지/임시카테고리

SQL 기초23 JOIN 두번째 (아직 갈길이 멀다 JOIN은 특히 더)

by 다니엘의 개발 이야기 2022. 8. 27.
320x100

#JOIN

 

#1 INNER JOIN

교집합

 

SELECT * FROM tableA

INNER JOIN tableB

ON tableA.col_match = tableB.col_match 

 

# 이렇게되면 중복되는 ‘테이블 값’이라도, 컬럼 값이 중복되지 않는다면

# 컬럼은 컬럼대로 쓰이지만 테이블 값에 대해서 2번에 걸쳐서 펼쳐질 수가 있다.

# 이를 방지 하기 위해서 다음의 코드를 고려해 볼 수 있다.

 

예시1

SELECT reg_id, Logins.name, log_id

FROM Registrations

INNER JOIN Logins

ON Registrations.name = Logins.name

 

예시2

SELECT payment_id, payment.customer_id, first_name

FROM payment

INNER JOIN customer

ON payment.customer_id = customer.customer_id


#2 OUTER JOIN

*이건 개념이 매우 다양하다

 

1)FULL OUTER JOIN

A문

SELECT * FROM tableA

FULL OUTER JOIN tableB

ON tableA.col_match = tableB.col_match

 

B문

SELECT * FROM tableB

FULL OUTER JOIN tableA

ON tableA.col_match = tableB.col_match

 

*1 A문과 B문을 보면 어디서 파일을 가져오는지가 틀리지만

00과 조인을 하겠다라는 것을 보면 결과적으론 같다.

따라서 A문 B문 모두 동일한 결과값을 가진다.

 

*2 FULL OUTER JOIN은 INNER JOIN과 반대되는 개념이다.

쉽게 합집합에서 교집합 뺀 모습이라고 생각하면 된다.

 

SELECT * FROM Registrations FULL OUTER JOIN Logins

ON Registrations.name = Logins.name

WHERE Registrations.reg_id IS null OR

Logins.log_id IS null


#3 LEFT JOIN

 

SELECT film.film_id, title, inventory_id, store_id

FROM film

LEFT JOIN inventory 

ON inventory.film_id = film.film_id

WHERE inventory.film_id IS null

 

#4 RIGHT JOIN

*RIGHT JOIN을 쓰든 RIGHT OUTER JOIN을 쓰든 같은 기능을 한다.

 

SELECT * FROM tableA

RIGHT OUTER JOIN tableB

ON tableA.col_match = tableB.col_match


#5 문답풀이

 

1)캘리포니아에 사는 사람들의 정보에 문제가 생겨서 이메일을 보내고자 한다.

 

여기서 체크한 포인트는 주소 테이블, 고객 테이블 이다.

그리고 주소 테이블과 고객 테이블에는 내가 원하는 리턴 정보가 있었고

둘이 동일한 컬럼으로써 사용하는 컬럼도 있었다.

그것을 바탕으로 조인해주었다.

방식은 일단 LEFT JOIN의 원리를 정확히 알고한건 아니지만

해도 문제될건 없을것같고, 문제가 되면 다른 조인 방법을 찾아보고자 일단 시도해봤고

결과는 성공이였다.

 

# 내코드

SELECT address.district, customer.email

FROM address

LEFT JOIN customer

ON address.address_id = customer.address_id

WHERE address.district LIKE 'California'

 

# 답안코드와 과정

 

처음엔

SELECT * FROM address

INNER JOIN customer

ON address.address_id = customer.address_id

로 접근했다.

 

그다음엔

SELECT * FROM address

INNER JOIN customer

ON address.address_id = customer.address_id

WHERE district = ‘California’

라고 해주었고 그다음엔

 

SELECT district, email FROM address

INNER JOIN customer

ON address.address_id = customer.address_id

WHERE district = ‘California’

 

라고 마무리를 지어주었다.

 

INNER JOIN은 교집합 출력이기 때문에

괜찮다고했으며, 실제로도 괜찮을것같다.


2)Nick Wahlberg라는 배우의 팬이 있는데,

이 배우가 나온 작품을 모두 알고 싶다고 한다.

 

이게 어려웠다. 처음으로 접하는 3개이상의 컬럼을 join해야하는 멀티 조인

음.. 

 

두번째 시도만에 성공은 했다.

다만, 만족스럽지 못한 점이 있다면

이건 여태까지 얕게 공부한 지식적 배경에 근거한 직감인데

메모리를 불필요하게 많이 썼기 때문에

결과값이 나오기까지 느리진 않았을까 싶다.

 

그리고 원래는 한번 시도하고 답안코드를 보고 복습하려고 했는데

그래도 구글링은 해보라고 해서 해서 결과를 냈다.

ANSI 표준 적인 방법과는 다르다.

 

내 코드

SELECT film.title, actor.first_name, actor.last_name

FROM actor, film_actor, film

WHERE (actor.actor_id = film_actor.actor_id)

AND film_actor.film_id = film.film_id

WHERE first_name = ‘Nick’

AND last_name = ‘Wahlberg

 

답안코드

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'

 

잡담이지만, 답안코드도 완전 느리고, ANSI 코드랑은 얼추 비슷한데도 느린걸보니

그냥 내가 쓰는 뭔가가 문제가 있는 듯하다.

로딩이 이번엔 3분 50초가 걸리네;

 

후기지만, 결과적으로 답은 다 맞췄다.

하지만 JOIN이 SQL의 핵심 기능인것 같은데도 불구하고

여전히 이해력이 낮다.

더 응용되고, 더 응용되면 아직 못풀 것 같다.

메모리 신경안쓰고 결과론 적으로 맞기만 하는 SQL 문이라면 이미 기초적으론 충분히 알것같은데

ANSI 규정에 의해서 짜임새를 맞춰가는건 거의 모르는것에 가까울 정도다.

공부하자.

300x250