Computer >> 컴퓨터 >  >> 프로그래밍 >> SQL

SQL CASE문 완벽 가이드 – 쿼리에서 IF/THEN 조건 로직 구현하기

데이터베이스를 다루다 보면 쿼리 안에서 if/then 형태의 조건 처리가 필요한 경우가 자주 있습니다. 예를 들어 직원 목록을 살펴보며 근속 기간이 1년을 넘은 직원의 수습 상태를 변경하거나, 리더보드의 플레이어 중 상위 3위 안에 든 사람에게 '우승자' 표시를 붙이는 경우를 생각해 볼 수 있습니다.

SQL에서 이런 조건 처리를 하려면 CASE 문을 사용해야 합니다. SQL CASE 문은 엑셀(Microsoft Excel)에서 if/then 절차를 실행하는 것과 비슷한 방식으로, 쿼리 안에서 조건 분기 로직을 구현할 수 있게 해줍니다.

이 글에서는 SQL CASE 문의 기본 개념과 쿼리 활용법을 살펴보고, 여러 조건을 결합하는 방법과 집계 함수(aggregate function)와 함께 사용하는 방법까지 알아보겠습니다.

쿼리 기본 복습

데이터베이스에서 정보를 조회하려면 쿼리(query)를 작성해야 합니다. 쿼리는 거의 항상 SELECT 문으로 시작하며, SELECT는 어떤 열(column)을 반환할지 데이터베이스에 지시하는 역할을 합니다. 또한 대부분의 쿼리에는 FROM 절이 포함되어 어느 테이블을 대상으로 작업할지 지정합니다.

SQL 쿼리의 기본 문법은 다음과 같습니다:

SELECT column_name FROM table_name WHERE conditions_are_met;

예시를 통해 확인해 보겠습니다. 아래 쿼리는 employees 테이블에 있는 모든 직원의 이름을 반환합니다:

SELECT name FROM employees;

실행 결과는 다음과 같습니다:

name
Luke
Mike
Hannah
Geoff
Alexis
Emma
Jonah
Adam

(8 rows)

여러 열을 조회하고 싶다면 열 이름을 쉼표로 구분해 나열하면 됩니다. 모든 열의 데이터를 가져오고 싶다면 테이블의 전체 열을 의미하는 별표(*) 연산자를 사용할 수 있습니다.

특정 조건에 맞는 레코드만 필터링하고 싶다면 WHERE 절을 사용합니다. 예를 들어 Albany 지점에 소속된 모든 직원의 이름을 찾는 쿼리는 다음과 같습니다:

SELECT name FROM employees WHERE branch = 'Albany';

실행 결과:

name
Emma
Jonah

(2 rows)

여기까지의 쿼리는 비교적 단순합니다. 그렇다면 쿼리를 실행하면서 if/then 연산을 수행하려면 어떻게 해야 할까요? 바로 이럴 때 SQL CASE 문이 유용합니다.

SQL CASE 문이란?

CASE 문은 SQL 코드에서 if/then 로직을 정의할 때 사용합니다. 예를 들어 근속 연수가 5년 이상인 모든 직원에게 급여를 인상해 주고 싶다면 CASE 문을 활용할 수 있습니다.

SQL CASE 문의 기본 문법은 다음과 같습니다:

SELECT column1_name,
	CASE WHEN column2_name = 'X' THEN 'Y'
		ELSE NULL END AS column3_name
	FROM table_name;

이 쿼리는 다소 복잡해 보이니 예제를 통해 동작 방식을 살펴보겠습니다. '이달의 직원(employee of the month)' 상을 5회 초과 받은 직원에게 200달러의 인상을 적용하고 싶다고 가정해 봅시다. 이 목표를 달성할 수 있는 SQL 문은 다음과 같습니다:

SELECT name,
	CASE WHEN employee_month_awards > 5 THEN 200
		ELSE NULL END AS pending_raise
	FROM employees;

검색형 CASE 표현식(searched case expression)의 실행 결과는 다음과 같습니다:

namepending_raise
Luke 
Mike 
Hannah 
Geoff 
Alexis 
Emma200
Jonah 
Adam200

(8 rows)

동작 방식을 하나씩 살펴보겠습니다. CASE 문은 각 레코드를 검사하며 조건식 employee_month_awards > 5가 참인지 평가합니다. 조건식이 참이면 pending_raise 열에 값 200이 출력되고, 거짓이면 null 값이 그대로 남습니다.

최종적으로 쿼리는 직원 이름 목록과 각 직원의 예정된 인상액(pending raise)을 반환합니다.

주목할 점은 SQL CASE 문이 실제 테이블에 새로운 열을 추가하지 않는다는 것입니다. 대신 SELECT 쿼리의 출력 결과에 임시 열을 만들어 누가 인상 대상인지 확인할 수 있게 해줍니다.

또한 인상 대상이 아닌 직원에게도 특정 값을 표시하고 싶다면 ELSE 절에서 NULL 대신 원하는 값을 지정하면 됩니다. 데이터를 특정 순서로 보고 싶다면 ORDER BY 절을 추가해 결과를 정렬할 수도 있습니다.

SQL CASE와 다중 조건

CASE 문은 하나의 쿼리에서 여러 번 사용할 수 있습니다. 예를 들어 상을 3개 이상 받은 직원에게는 50달러를, 5개를 초과해 받은 직원에게는 200달러를 인상해 주고 싶다면 다음과 같이 작성할 수 있습니다:

SELECT name,
	CASE WHEN employee_month_awards > 5 THEN 200
		WHEN employee_month_awards > 3 THEN 50
		ELSE 0 END AS pending_raise
	FROM employees;

쿼리 출력 결과는 다음과 같습니다:

namepending_raise
Luke50
Mike0
Hannah0
Geoff0
Alexis0
Emma200
Jonah50
Adam200

(8 rows)

이 예제에서 CASE 문의 조건들은 작성된 순서대로 평가됩니다.

즉, 쿼리는 먼저 상을 5개 초과 받은 사람을 찾아 인상액을 200으로 설정합니다. 그다음 상을 3개 초과 받은 사람을 찾아 인상액을 50으로 설정합니다. 마지막으로 어떤 조건에도 해당하지 않는 직원의 인상액은 0으로 설정됩니다.

그런데 이 코드는 더 효율적으로 개선할 수 있습니다. 프로그램이 의도대로 동작하도록 문장의 순서에 의존하기보다는, 서로 겹치지 않는 조건을 작성하는 것이 좋습니다. 아래 쿼리는 위와 동일하게 동작하지만 AND 연산자를 사용해 직원이 받은 상의 개수를 명확하게 검사합니다:

SELECT name,
	CASE WHEN employee_month_awards >= 3 AND employee_month_awards <= 5 THEN 50
		WHEN employee_month_awards > 5 THEN 200
		ELSE 0 END AS pending_raise
	FROM employees;

이 쿼리는 앞선 쿼리와 동일한 결과를 반환합니다. 하지만 이 버전은 CASE 문의 순서에 의존하지 않기 때문에 조건을 잘못 배치해 발생하는 실수 가능성이 줄어듭니다.

SQL CASE와 집계 함수

CASE는 집계 함수와 함께 사용할 수도 있습니다. 특정 조건을 충족하는 행만 세고 싶을 때 특히 유용합니다. 예를 들어 200달러 보너스를 받을 자격이 있는 직원이 몇 명인지 알고 싶다면 CASE를 집계 함수와 함께 사용하면 됩니다.

CASE를 집계 함수와 함께 사용하는 문법은 다음과 같습니다:

SELECT column1_name,
	CASE WHEN column2_name = 'X' THEN 'Y'
		ELSE NULL END AS column3_name,
		COUNT(1) AS count
	FROM table_name
GROUP BY column3_name;

예제를 통해 살펴보겠습니다. 50달러 이상의 보너스를 받을 자격이 있는 직원이 몇 명인지 알고 싶다고 가정해 봅시다. 다음 쿼리로 이 정보를 얻을 수 있습니다:

SELECT 
	CASE WHEN employee_month_awards >= 3 AND employee_month_awards <= 5 THEN 50
		WHEN employee_month_awards > 5 THEN 200
		ELSE 0 END AS pending_raise,
		COUNT(1) AS count
	FROM employees
GROUP BY pending_raise;

쿼리 실행 결과는 다음과 같습니다:

pending_raisecount
503
03
2002

결과에서 볼 수 있듯이, 쿼리는 직원들이 받을 예정인 인상액 목록과 각 유형별 인원수를 반환했습니다. 즉, 50달러 인상 대상이 3명, 인상 대상이 아닌 직원이 3명, 200달러 인상 대상이 2명입니다.

마무리

이번 튜토리얼에서는 SQL CASE 문의 기본 개념과 쿼리에서 if/then 로직을 구현하는 방법을 살펴봤습니다. 또한 여러 조건을 결합해 사용하는 방법과 집계 함수와 함께 활용하는 방법도 알아봤습니다.

복습 차원에서, 올바른 CASE 표현식은 다음 규칙을 따라야 합니다:

  • CASE 문은 SELECT 절 안에 위치해야 합니다.
  • CASE 문에는 WHEN, THEN, END 요소가 반드시 포함되어야 합니다.
  • 여러 개의 WHEN 문과 ELSE 절은 선택적으로 사용할 수 있습니다.
  • AND, OR 같은 조건 연산자는 WHENTHEN 절 사이에서 사용할 수 있습니다.

이제 여러분도 SQL 전문가처럼 CASE 문을 활용할 준비가 되었습니다!