[SQL] #3. INNER JOIN
오늘은 SQL 문법 중 가장 많이 쓰이고, 코딩테스트 난이도도 어렵게 출제되는 INNER JOIN 문에 대해 간략히 알아보고 이를 활용한 예제들을 포스팅 해보려고 합니다.
먼저 JOIN 문에는 어떤 종류가 있는지, 특징은 무엇인지 대략적으로 살펴보고 시작하겠습니다.
1️⃣ JOIN
JOIN은 말 그대로 SQL에서 두 테이블을 “조인” 하는 것입니다. 조인은 곧 두 개 이상의 테이블을 일정한 조건에 따라 결합한다는 의미로 볼 수 있습니다. 예전에 수학시간에 배웠던 집합 이론을 생각하시면 됩니다!
JOIN 문에는 여러 종류가 있습니다.
1. INNER JOIN
INNER JOIN은 여러 테이블들에서 주어진 조건을 공통으로 만족하는 데이터만을 추출합니다. 집합론적으로 보면 두 테이블의 교집합 인 데이터를 추출한다고 볼 수 있습니다.
2. OUTER JOIN
OUTER JOIN에는 LEFT OUTER JOIN, RIGHT OUTER JOIN, FULL OUTER JOIN 이 있습니다.
LEFT OUTER JOIN은 두 테이블이 있을 때 첫번째 테이블을 기준으로 두번째 테이블을 결합하는 역할을 합니다. 즉 첫번째 테이블의 행은 조건에 상관없이 가져오지만, 두번째 테이블에서는 조건에 만족하는
행만 가져옵니다. 만약 두번째 테이블이 조건을 만족하지 못하는 경우, 해당 데이터는 NULL로 표시됩니다. 이 부분에 대해서는 문제를 통해 더 자세히 다루겠습니다.
RIGHT OUTER JOIN은 LEFT OUTER JOIN과 반대로 두번째 테이블을 기준으로 첫번째 테이블을 결합합니다.
FULL OUTER JOIN은 LEFT OUTER JOIN과 RIGHT OUTER JOIN을 합친 것으로, 두 테이블에 해당하는 데이터를 조건에 맞게 모두 보여줍니다.
3. SELF JOIN
SELF JOIN은 SELF 라는 말 그대로 같은 테이블 두 개를 JOIN 하는 것을 의미합니다. SELF JOIN에 대한 예시는 뒤에서 다루겠습니다.
2️⃣ INNDER JOIN 예제
이제 JOIN문의 역할, 종류에 대해서 알아봤으니 JOIN문을 사용하는 예제 3개를 같이 풀어보고 살펴보겠습니다!
(1) Employees Earning More Than Their Managers
Problem
The Employee table holds all employees including their managers. Every employee has an Id, and there is also a column for the manager Id.
Given the Employee table, write a SQL query that finds out employees who earn more than their managers. For the above table, Joe is the only employee who earns more than his manager.
Solution
SELECT e1.Name AS Employee
FROM Employee AS e1
INNER JOIN Employee AS e2 ON e1.ManagerId = e2.Id # Step 1
WHERE e1.Salary > e2.Salary # Step 2
이 문제는 사원(Employee) 테이블에서 매니저의 월급보다 더 많은 월급을 받는 사원을 추출하는 문제입니다. 이 때 사용하는 테이블은 사원 테이블 하나로, 고로 이 문제는 SELF JOIN 문제입니다.
문제를 풀기 위한 과정은 다음과 같습니다.
Step 1
먼저 위에서 주어진 사원 테이블을 보면 사원의 이름을 나타내는 Name 칼럼, 사원의 매니저를 나타내는 ManagerId 가 있습니다. 현재 이 문제는 사원의 Salary, 매니저의 Salary를 비교해야하는 문제이기 때문에 사원 테이블에 ManagerId에 해당하는 정보를 결합해야합니다.
즉, 위 테이블에서 첫번째 사원 Joe의 매니저의 Id가 3이므로, 오른쪽으로 Id가 3에 해당하는 Sam의 Salary 정보를 붙이는 것이죠! 이러한 맥락에서 이 문제는 SELF JOIN 문제라고 하는 것입니다. 이를 구현하기 위해 INNER JOIN 문을 사용합니다. SELF JOIN 문제를 풀 때는 같은 테이블을 두 번 쓰기 때문에 데이터 테이블간 충돌이 발생할 수 있습니다. 이를 방지하기 위해 ALIAS 를 사용하여 두 테이블을 구분합니다. INNER JOIN에 대한 조건은 ON 절에 설정합니다.
Step 2
이렇게 JOIN을 했으니 다음 조건을 적용합니다. 문제에서는 매니저보다 많은 월급을 받는 사원의 이름을 추출하라 했는데요, 이를 위해 WHERE 절에서 조건문을 구현합니다. WHERE 절에서도 같은 칼럼 Salary 가 두 번 등장하므로 충돌을 피하기 위해 ALIAS를 사용합니다.
(2) Rising Temperature
Problem
Write an SQL query to find all dates’ id with higher temperature compared to its previous dates (yesterday). The query result format is in the following example:
Solution
SELECT today.id as id
FROM Weather AS today
INNER JOIN Weather AS yesterday ON date_add(yesterday.recordDate, INTERVAL 1 DAY) = today.recordDate # Step 1
WHERE today.Temperature > yesterday.Temperature # Step 2
이 문제 역시 같은 테이블끼리 조인하는 SELF JOIN 문제입니다. 따라서 먼저 다룬 문제처럼 ALIAS를 사용하여 두 테이블을 구분해야한다는 것을 먼저 명심해야 합니다. 이 문제에서는 어제 기온과 오늘의 기온을 비교하는 문제이기 때문에 ALIAS를 사용하여 각각 today, yesterday로 명명했습니다.
Step 1
먼저 두 테이블을 JOIN 합니다. 여기서 주의할 점은 “어제” 날짜와 “오늘” 날짜를 조인해야한다는 것입니다! 그러면 첫번째 테이블(today)의 recordDate가 2015-01-02 라면 두번째 테이블(yesterday)의 recordDate 2015-01-01 를 결합시켜야 합니다.
이를 구현하기 위해 date_add
라는 함수를 사용합니다. date_add
에는 기준 날짜, 그리고 더해줄 날짜를 입력합니다. 위와 같이 구현하기 위해 yeserday의 recordDate + 1 = today 의 recordDate 를 ON 조건절에 부여하면 해결됩니다. 코드는 soluation 에 있습니다.
Step 2
그 다음 어제보다 오늘 더 기온이 높은 경우의 id를 찾기 위해 WHERE 조건절에 해당 조건을 부여합니다. 이 역시 ALIAS를 사용하여 today.Temperature > yesterday.Temperaure 과 같이 조건절을 부여하면 됩니다.
댓글남기기