Programme/SQL

[SQL] 테이블 조회(2) - INNER JOIN, OUTER JOIN, CASE WHEN

프랑스어전공 2023. 12. 11. 16:16

4. 데이터 조회(2)

INNER JOIN

두 테이블간 조인 조건을 만족하는 행을 반환할 때 사용하는 구문이다. 두 테이블의 교집합이라고 생각하면 이해하기 쉽다.

create table world_tour1 (
  cast    varchar(20),
  name    varchar(10)
);

create table world_tour2 (
  cast    varchar(20),
  name    varchar(10)
);

insert into world_tour1 values ('기안84','김희민');
insert into world_tour1 values ('이시언','이보연');
insert into world_tour1 values ('빠니보틀','박재한');

insert into world_tour2 values ('기안84','김희민');
insert into world_tour2 values ('덱스','김진영');
insert into world_tour2 values ('빠니보틀','박재한');

 

FROM 에서 쓰인 테이블명을 아래와 같이 wt1, wt2로 정의해서 이후에 테이블을 쓸 때 편하게 불러올 수 있게 하였다. INNER JOIN은 데이터를 불러오는 FROM 뒤에 쓰도록 하자.

 

SELECT * FROM world_tour1 wt1 INNER JOIN world_tour2 wt2 ON wt1.cast = wt2.cast;

 

 

주의할 점이 있다. SELECT 문에 컬럼을 적을때 중복된 컬럼이 있다면 어느 테이블의 컬럼인지 확실히 적어줘야 한다는 것.

#case 컬럼이 wt1에도 있고 wt2에도 있기 때문에 오류가 난다.
SELECT case FROM world_tour1 wt1  INNER JOIN world_tour2 wt2 ON wt1.cast = wt2.cast;
    
#어느 테이블의 피처인지 정확히 정의해주주자.
SELECT wt1.cast FROM world_tour1 wt1  INNER JOIN world_tour2 wt2 ON wt1.cast = wt2.cast;

 

 

실무에선 INNER JOIN으로 조건을 걸어주기 보다는 WHERE절로 조건을 걸어준다고 한다. INNER JOIN을 썼을 때보다 직관적으로 이해하기 쉬운거같다.

SELECT wt1.cast FROM world_tour1 wt1, world_tour2 wt2 WHERE wt1.cast = wt2.cast; #같을경우

 

 

특정값을 제외 하고 싶을때는 and 를 이용하여 어떤 값을 제외할지 정의하면 된다.

SELECT wt1.name  FROM world_tour1 wt1, world_tour2 wt2 WHERE wt1.cast = wt2.cast and wt1.cast <> '기안84';

OUTER JOIN

JOIN 조건에서 동일한 값이 없는 행도 반환할 때 사용한다. 즉 두 테이블을 JOIN 할 경우, 조건에 맞지 않는 데이터도 표시하고 싶을 때 OUTER JOIN을 사용한다. 그렇기에 LEFT 테이블에 초점을 둘지, RIGHT 테이블에 초점을 둘지에 따라서 LEFT JOIN, OUTER JOIN이 있지만 실무에선 팀 내 쿼리의 가독성을 위해 LEFT JOIN 만 사용한다고 한다.

INNER JOIN 을 썼던 위치에 쓰면 된다.

SELECT * FROM world_tour1 wt1 LEFT OUTER JOIN world_tour2 wt2 on wt1.cast = wt2.cast;
SELECT * FROM world_tour1 wt1 RIGHT OUTER JOIN world_tour2 wt2 on wt1.cast = wt2.cast;

하지만 이렇게 NULL값 제외 조건 없이 쓰면 NULL값도 같이 출력되게 된다. 따라서 NULL 값을 제외하고 보고 싶을경우 where 절을 통해 조건을 걸어주면 된다.

 

 

 

CASE WHEN

Case when 구문은 SELECT 절에 쓰이며 대표적으로 2가지 쓰임새가 있다. 새로운 열을 생성하는 경우나 열을 집계하는 경우 (집계함수와 함께 사용, 집계 열에 집계함수를 적용한다) 에 사용한다.



CASE WHEN 구문을 표현할때 두가지 표현식이 있다.

  1. 단순 CASE 표현식
  2. 검색 CASE 표현식

단순 CASE 표현식에선 equal 조건만 사용 가능하고 집계 함수를 사용할 경우 검색 CASE 표현식으로 사용해야한다.

create table employees (
    emp_nm   varchar(20),
    gender   varchar(1),
    hire_dt  date
);

insert into employees values ('성덕선','F','20230506');
insert into employees values ('김정봉','M','20221217');
insert into employees values ('최택','M','20200314');
insert into employees values ('김정환','M','20230506');
insert into employees values ('성보라','F','20210811');

gender의 값에 따라 ‘남자’와 ‘여자’로 나누어보자. 두가지 표현식을 비교해서 확인해보자.

 

 

1. 단순 CASE 표현식

SELECT emp_nm,
	CASE gender
	WHEN 'F' THEN '여자'
	WHEN 'M' THEN '남자'
	ELSE '해당없음' END AS gender
  FROM employees;

 

2.  검색 CASE 표현식

SELECT emp_nm,
	CASE WHEN gender = 'F' THEN '여자'
		 WHEN gender = 'M' THEN '남자'
	ELSE '해당없음' END AS gender
  FROM employees;

 

검색 CASE 표현식에선 집계함수가 같이 쓰인 것을 볼 수 있다. 반면에 단순 CASE표현식에선 equal조건만 사용할 수 있다.

F는 ‘여자’로 M은 ‘남자’로 잘 표현된 걸 볼 수 있다. 만약 ELSE를 쓰지 않는 다면 ELSE값에 대해선 Null처리된다.

 

 

이렇게 범위 조건이 포함됐을 경우 단순 CASE 표현식으로는 작성할 수 없기 때문에 참고하자.

아래 쿼리는 2023년 이후 입사했을 경우 ‘신규사원’으로 return하고 그 이전일 경우 ‘기존사원’으로 return한다.

SELECT emp_nm, hire_dt,
	CASE WHEN hire_dt > '20230101000000' THEN '신규사원' #2023년 이전이면 기존사원 
	ELSE '기존사원' END AS emp_type
  FROM employees;

 

CASE WHEN 구문을 쓸때 주의할 점이 있다. CASE 조건식에서 조건을 여러개 썼을 때, 맨 윗줄의 조건이 실행되게 된다면 아랫줄은 skip된다.

SELECT emp_nm, hire_DT,
	CASE WHEN hire_dt < '20230101' THEN '기존사원'
   		 WHEN hire_Dt < '20220101' THEN '옛날사원'
	ELSE '신규사원' END AS emp_type
  FROM employees;

 

 

결과를 보면 두번째 조건식은 반영되지 않은 것을 볼 수 있다.