본문 바로가기

개발/Back-end

SQL이 어려운 이유 2- JOIN

반응형

이번 편은 저번 편(GROUP BY) 편에 이어 두번째 편입니다.

개인적으로 근래 추세가 쿼리를 복잡하게 짜는 것도 아니고 최대한 단순하게 구성하는 것이기에 구글링 하면서 하면 문제 없이 풀 줄 알았는데 생각보다 막상 모의고사에서 만나니 생각보다 어렵다는 생각이 들었고 공부를 해야겠다는 생각이 들었다. 그중 하나가 JOIN이다.

해당 문제는 유출할 수가 없어서 사진을 올리지 못하지만 간단하게 애기 하면 테이블 3개를 합쳐야 되는 문제 였다. 어려웠다. 못 풀었다. SQL문제는 구글링을 통해 충분히 풀 수 있다고 생각했는데 그 오만한 생각이 과감히 깨지는 순간이었다. 그렇기에 이 시리즈를 통해 공부하려고 한다.

 

일단 프로그래머스에서 제공하는 SQL 고득점 Kit를 풀었다. Join 과 Group by 에 대한 개념을 잡고 간다. 여기에 조금 더 추가하여 Join에 대해 알아보려 한다.

조인은 삼국지에서 내가 애정하는 문무겸비한 장수.. 데이터베이스에서 테이블 간의 결합을 이야기한다. 즉 두개 이상의 테이블에 대해서 결합하여 나타낼때 조인이라는 것을 이용한다.

조인의 종류는 4가지가 있는데

  1. 이너조인
  2. 아우터 조인
  3. 크로스 조인
  4. 셀프조인

이 있다.

이너조인

 

이너조인은 위와 같이 우리가 조인하고자 하는 두개의 테이블에서 공통된 요소들을 통해 결합하는 조인 방식이다. 즉, 우리가 하고자 했던, 직원들의 이름과 부서명을 같이 출력하는데 있어서 사용되는 가장 일반적인 조인이다.

SELECT employee.empName, department.deptName
FROM employee 
JOIN department ON employee.deptNo = department.deptNo

 

 

sql에서도 단순히 조인을 사용할 때는 암묵적으로 이너조인을 뜻한다.

아우터 조인

아우터 조인은 위의 그림과 같이 left join, right join 그리고 두개를 합친 pull join 총 3개가 있다.

select employee.empName, department.deptName from employee left join department on employee.deptNo = department.deptNo

SELECT employee.empName, department.deptName 
FROM employee left join department 
ON employee.deptNo = department.deptNo

공통된 데이터가 없고 누락된 데이터를 함께 보고 싶은 경우에 아우터 조인을 이용한다.

left, right, full 조인이 존재한다.

크로스 조인

이너 조인과 아우터 조인은 두 테이블간의 특정 기준에 의해 데이터 결합의 결과를 보여주는 방식이었다면, 크로스 조인은 특정 기준 없이, 두 테이블간 가능한 모든 경우의 수에 대한 결합을 결과로 보여주는 방식이다.

SELECT employee.empName, department.deptName 
FROM employee cross 
JOIN department

셀프 조인

자기 스스로를 결합시키는 조인이다. 조인을 할 때 기본 테이블 이외에 참조하는 테이블이 다른 테이블이 아닌 자기 자신이라는 점이 중요하다. 이때 우리는 위에서 각 테이블에 대한 별칭을 선택적으로 사용했지만 셀프 조인시에는 별칭을 필수로 입력해주어야 한다. 같은 테이블을 2개 또는 그 이상 사용하는데 별칭을 정해주지 않으면 혼동되기 때문이다.

select emp1.empNo 사원번호, emp1.empName 직원이름, emp1.manager 매니저 번호, emp2.empName 매니저이름 from employee emp1 join employee emp2 on emp1.manager = emp2.empNo

위의 조인들은 좀 더 세분화된 조인이다. 실제 현업에서 사용하는 쿼리문과는 조금 다르다.

나는 대부분의 문제를 left join을 이용해서 풀었따.

문제 : 오랜기간 보호한 동물

SELECT ANIMAL_INS.NAME, ANIMAL_INS.DATETIME 
FROM ANIMAL_INS 
LEFT JOIN ANIMAL_OUTS 
ON (ANIMAL_INS.ANIMAL_ID = ANIMAL_OUTS.ANIMAL_ID) 
WHERE ANIMAL_OUTS.ANIMAL_ID is null 
ORDER BY ANIMAL_INS.DATETIME 
LIMIT 3;

서브 쿼리를 날리는 등 여러가지 풀이 법이 있었지만 나는 join을 이런 식으로 조건을 주어서 해결하였는데 두가지 테이블에서 내가 원하는 정보들을 명확히 한 후 join을 하고 on을 통해 조건을 나누었다. 추가 적인 조건은 where로 통해 구현했으면 별칭을 헷갈리는 것을 방지하기 위해 오리려 사용하지 않았는데 그 부분이 좀 더 초보자에게 있어서 효율적인것 같다.

문제 : 있었는데요 없었습니다.

SELECT ANIMAL_OUTS.ANIMAL_ID, ANIMAL_OUTS.NAME 
FROM ANIMAL_OUTS 
LEFT JOIN ANIMAL_INS 
ON (ANIMAL_INS.ANIMAL_ID = ANIMAL_OUTS.ANIMAL_ID) 
WHERE ANIMAL_INS.DATETIME > ANIMAL_OUTS.DATETIME 
ORDER BY ANIMAL_INS.DATETIME ;

조인은 이 정도로 짚고 넘어가면 좋을 거 같다. sql을 풀면서 좀 더 어려운 문제에 봉착한다면 그때 다시 짚고 넘어가도록 하자.

Reference

https://doorbw.tistory.com/223

반응형

'개발 > Back-end' 카테고리의 다른 글

MongoDB vs MySQL  (0) 2021.07.17
데이터 베이스 스키마 (Database schema)  (2) 2021.07.11
Sequelize 간단히 알아보기  (0) 2021.07.08
SQL을 어려운 이유 1 - GROUP BY  (0) 2021.06.26
Node js 자주 사용하는 미들웨어  (0) 2021.06.22