컴퓨터공학

복잡한 조건 분기 처리 전략: SQL로 비즈니스 로직을 설계하는 기술

nyambu 2025. 5. 16. 22:00

복잡한 조건 분기 처리 전략
복잡한 조건 분기 처리 전략

1. SQL에서 분기 처리란 무엇인가?

 SQL은 기본적으로 선언형 언어로, 흐름 제어보다는 “무엇을 조회할 것인가”를 선언하는 방식이다. 하지만 실무에서는 데이터의 상태에 따라 조건을 다르게 적용해야 하는 경우가 많다. 예를 들어 다음과 같은 경우가 그렇다.

  • 주문 상태가 ‘결제완료’일 때만 배송정보 출력
  • 포인트가 1000 이상이면 등급을 ‘Gold’로 표시
  • 로그인 경로가 모바일일 때만 푸시 알림 여부 체크

 이처럼 한 컬럼의 값에 따라 출력 내용을 바꾸거나 계산 방식을 변경해야 할 때, SQL에서는 CASE, IF, WHEN, COALESCE, NULLIF 같은 분기 구문을 활용하게 된다.


2. CASE WHEN 구문의 기본 사용법

 CASE는 SQL에서 가장 대표적인 분기 제어문이다. 특정 컬럼의 값에 따라 다른 결과를 반환하거나, 다중 조건에 따라 가공된 결과를 출력하는 데 쓰인다.

SELECT user_id,
       CASE 
           WHEN point >= 1000 THEN 'GOLD'
           WHEN point >= 500 THEN 'SILVER'
           ELSE 'BRONZE'
       END AS grade
FROM users;

위 쿼리는 사용자의 포인트에 따라 등급을 분기 처리하는 간단한 예제지만, 실무에서는 이 CASE문이 하나의 SELECT문에 5~6개 이상 중첩되는 경우도 많다. 중요한 팁은 다음과 같다.

  • CASE WHEN 조건 THEN 결과 구문은 IF문과 다르게 가독성이 높고 중첩이 가능
  • ELSE 절은 생략 가능하지만, 모든 조건에서 기본값을 명시하는 습관이 좋다
  • 숫자, 문자열, 날짜 등 모든 타입에 적용 가능하다

3. 다중 조건 조합을 구조화하는 방식

 실무에서는 단순한 분기가 아니라 다중 조건이 결합된 경우가 많다. 예를 들어 다음과 같은 조건을 생각해보자.

  • 회원이면서
  • 최근 30일 내 결제 이력이 있고
  • 포인트가 500 이상인 경우 등급을 '우수', 그 외는 '일반'

 이 조건을 CASE문 안에 모두 넣는다면 다음처럼 표현할 수 있다.

SELECT *,
       CASE 
           WHEN is_member = 1 AND last_payment_date >= CURDATE() - INTERVAL 30 DAY AND point >= 500 
           THEN '우수'
           ELSE '일반'
       END AS member_grade
FROM users;

이런 식으로 복합 조건도 하나의 CASE 안에 묶을 수 있지만, 조건이 길어지면 가독성이 떨어지므로 다음과 같이 전략을 취하면 좋다.

  1. 조건을 서브쿼리에서 먼저 처리하고, 메인 쿼리에선 CASE만 사용
  2. WITH 절로 조건 분기를 정리해 중복 제거
  3. 조건이 너무 길 경우 CASE 안에서 다시 CASE를 쓰지 말고 쿼리를 나누는 것도 고려

4. 출력값에 따른 계산 방식 분기

 조건에 따라 출력뿐 아니라 계산 방식 자체가 달라져야 하는 경우도 있다. 예를 들어 상품의 할인율이 상태에 따라 다르다면 다음과 같이 처리할 수 있다.

SELECT product_id,
       price,
       CASE 
           WHEN discount_type = 'fixed' THEN price - discount_value
           WHEN discount_type = 'percent' THEN price * (1 - discount_value / 100)
           ELSE price
       END AS final_price
FROM products;

 이 구조는 실무에서 매우 자주 사용된다.

  • 정률 / 정액 할인,
  • 조건별 세금 계산,
  • 상태에 따라 수수료율 적용

 복잡한 계산 로직을 SQL에서 처리할 수 있다면 불필요한 로직을 애플리케이션에서 반복하지 않아도 되므로 데이터 처리 효율이 크게 향상된다.


5. CASE와 JOIN을 조합하는 패턴

 CASE는 단독으로 쓰일 때보다 JOIN과 함께 쓰일 때 진가를 발휘한다. 예를 들어 주문 테이블과 사용자 테이블을 조인한 후, 사용자 상태에 따라 주문 처리 여부를 나누는 방식이다.

SELECT o.order_id, u.user_id,
       CASE 
           WHEN u.status = 'active' THEN '정상처리'
           WHEN u.status = 'suspended' THEN '보류'
           ELSE '차단'
       END AS order_status
FROM orders o
JOIN users u ON o.user_id = u.user_id;

이 구조는 실무에서 다음처럼 자주 쓰인다.

  • 사용자 상태, 상품 상태, 이벤트 참여 여부 등에 따라 UI 다르게 구성
  • 권한별 기능 노출 여부 판단
  • 내부 정책에 따라 행동 흐름 분기

 복잡한 비즈니스 로직이 데이터 레벨에서 처리되는 구조이기 때문에, JOIN + CASE 구조는 SQL 설계의 핵심 패턴 중 하나이다.


6. NULL 처리와 조건 결합: COALESCE, NULLIF

 SQL의 분기 처리에서 빠질 수 없는 게 바로 NULL 값 처리다. 특히 NULL 값이 자주 발생하는 컬럼에서는 분기를 단순히 = 연산으로 처리하면 조건이 누락되거나 잘못된 결과가 나올 수 있다.

6-1. COALESCE

 COALESCE는 여러 인자 중 NULL이 아닌 첫 번째 값을 반환하는 함수다.

SELECT COALESCE(nickname, username, '사용자') AS display_name
FROM users;

→ 닉네임이 있으면 닉네임, 없으면 아이디, 그것도 없으면 ‘사용자’로 표시

6-2. NULLIF

 NULLIF는 두 인자가 같으면 NULL을 반환하고, 그렇지 않으면 첫 번째 값을 반환한다. 주로 0으로 나누는 오류 방지나, 비교 제외 조건 처리에 사용된다.

SELECT total / NULLIF(count, 0) AS avg
FROM stats;

→ count가 0일 경우 0으로 나누는 오류 방지

 

 이 두 함수는 CASE와 함께 쓰이면 깔끔한 예외 처리를 위한 훌륭한 도구가 된다.


7. 조건 분기 쿼리의 유지보수 전략

 조건 분기 로직은 시간이 지날수록 복잡해지고, 유지보수가 어려워진다. 다음과 같은 전략을 적용하면 쿼리를 더 읽기 쉽고 변경하기 쉽게 만들 수 있다.

  1. CASE문을 가독성 좋게 정렬한다
    • 조건이 많아질수록 WHEN 절마다 줄바꿈, 들여쓰기 필수
  2. 반복되는 조건은 WITH절 또는 서브쿼리로 뽑는다
    • 조건을 한번 정의하고, 여러 곳에서 재사용
  3. UI 로직은 SQL로 과도하게 넘기지 않는다
    • 조건이 너무 UI 중심이라면, 애플리케이션에서 처리하는 게 나을 수 있음

 실무에서는 쿼리 성능만큼이나 **"읽고 이해하기 쉬운 구조"**가 중요하다. 조건이 늘어날수록 구조화, 정리, 주석이 필수다.


8. 실전 예제: 상태·날짜·범주별 결합 조건 처리

 실제 실무 시나리오를 가정해보자. “최근 30일 이내에 구매한 사용자 중, 회원 등급이 Gold 이상이며, 구매한 상품 카테고리가 '프리미엄'일 경우만 추천 대상에 포함” 이를 SQL로 풀면 다음과 같다.

SELECT u.user_id,
       CASE 
           WHEN u.grade IN ('GOLD', 'PLATINUM')
             AND o.order_date >= CURDATE() - INTERVAL 30 DAY
             AND p.category = '프리미엄'
           THEN '추천대상'
           ELSE '일반고객'
       END AS recommend_flag
FROM users u
JOIN orders o ON u.user_id = o.user_id
JOIN products p ON o.product_id = p.product_id;

이 예시에는 조건 분기 전략의 거의 모든 요소가 들어 있다:

  • 다중 JOIN
  • 날짜 조건
  • 범주 조건(category)
  • 등급 조건
  • CASE 기반 플래그 출력

 이처럼 실무에서는 단일 조건이 아니라, 결합 조건을 쿼리로 논리적으로 표현하는 능력이 중요하다.


9. 조건 분기와 통계 쿼리의 결합

 단순히 결과를 다르게 출력하는 것뿐만 아니라, 조건에 따라 집계나 통계 수치를 달리 계산해야 하는 상황도 많다. 예를 들어, 상태값이 '배송완료'인 주문만 카운트하거나, 회원 등급에 따라 누적 금액을 다르게 계산하는 식이다.

SELECT
  COUNT(*) AS total_orders,
  COUNT(CASE WHEN status = '배송완료' THEN 1 END) AS completed_orders,
  SUM(CASE WHEN user_grade = 'VIP' THEN amount ELSE 0 END) AS vip_total
FROM orders;

이 방식은 실무 대시보드나 관리자 통계 페이지에서 매우 자주 등장한다.

9-1. 조건이 많을수록 깔끔하게 구성해야

예: 상태별 주문 건수, 취소율, 환불율을 동시에 출력하려면 CASE 문을 적절히 구조화해서 중복 없이 집계하는 것이 중요하다.

SELECT
  COUNT(*) AS total,
  COUNT(IF(status = 'CANCEL', 1, NULL)) AS cancel_count,
  COUNT(IF(status = 'RETURN', 1, NULL)) AS return_count,
  COUNT(IF(status IN ('CANCEL', 'RETURN'), 1, NULL)) / COUNT(*) AS issue_rate
FROM orders;

 조건을 수치 계산과 결합하면 보고서용 SQL, BI 대시보드, 지표 쿼리 등 다양한 곳에서 재사용이 가능하다. 이 또한 분기 처리 전략의 확장된 형태라고 볼 수 있다.