CASE WHEN 구문의 활용법 – 조건 분기와 표현식을 동시에 해결하는 방법

Posted by heoncode
2025. 4. 11. 21:59 SQL 기초 정리
728x90
반응형
SMALL

SQL에서 조건에 따라 다른 값을 출력해야 할 때 CASE WHEN 구문을 사용합니다. 이는 프로그래밍 언어에서의 if-else처럼 조건 분기를 처리할 수 있도록 도와주며, 특히 SELECT 문 안에서 동적으로 컬럼 값을 제어할 때 자주 사용됩니다.

CASE WHEN의 기본 구조

CASE 구문은 다음과 같은 형식으로 작성합니다.

SELECT 컬럼명,
       CASE
           WHEN 조건1 THEN 결과1
           WHEN 조건2 THEN 결과2
           ELSE 기본값
       END AS 별칭
FROM 테이블명;

조건이 참인 첫 번째 WHEN 절이 실행되고, 해당 조건이 모두 거짓인 경우 ELSE 절의 값이 반환됩니다.

실무 예시: 고객 등급 분류

예를 들어, 고객의 구매 금액을 기준으로 등급을 나누는 쿼리는 다음과 같습니다.

SELECT 고객명,
       구매금액,
       CASE
           WHEN 구매금액 >= 100000 THEN 'VIP'
           WHEN 구매금액 >= 50000 THEN '우수'
           ELSE '일반'
       END AS 고객등급
FROM 고객테이블;

이 쿼리를 사용하면 금액에 따라 각 고객이 어떤 등급인지 자동으로 분류할 수 있습니다.

GROUP BY, ORDER BY와 함께 사용

CASE 문은 GROUP BYORDER BY와 함께 쓰일 때도 강력한 유연성을 발휘합니다. 예를 들어, 지역별로 '수도권'과 '비수도권'을 나눠 집계하고 싶을 때는 다음과 같이 활용합니다.

SELECT
    CASE
        WHEN 지역 IN ('서울', '경기', '인천') THEN '수도권'
        ELSE '비수도권'
    END AS 권역,
    COUNT(*) AS 고객수
FROM 고객테이블
GROUP BY
    CASE
        WHEN 지역 IN ('서울', '경기', '인천') THEN '수도권'
        ELSE '비수도권'
    END;

주의할 점

  • CASE 구문은 WHERE 절에서 직접 사용할 수 없습니다. 조건 분기가 필요한 경우엔 서브쿼리나 CTE(Common Table Expression)로 처리하는 것이 일반적입니다.
  • 조건 순서가 중요합니다. 먼저 작성된 WHEN 조건부터 평가되므로, 조건이 중첩될 수 있는 경우에는 우선순위를 고려해야 합니다.

마무리

CASE WHEN 구문은 SQL에서 데이터를 조건에 따라 분기해 보여줄 때 매우 유용한 도구입니다. 특히 복잡한 조건을 단일 컬럼 안에서 처리할 수 있어 가독성과 유지보수 측면에서도 장점이 많습니다. 실무에서도 흔히 사용되는 만큼, 다양한 상황에 적용해보며 익숙해지는 것이 중요합니다.

#SQL #CASE문 #조건분기 #SQL기초 #WHENTHEN #쿼리작성팁 #SELECT문 #데이터분석

728x90
반응형
LIST

COUNT(*)와 COUNT(컬럼명)의 차이 – 결과는 비슷해도 의미는 다르다

Posted by heoncode
2025. 4. 11. 17:17 SQL 기초 정리
728x90
반응형
SMALL

SQL에서 자주 사용하는 집계 함수 중 하나인 COUNT()는 단순히 행의 수를 세는 데에 유용합니다. 하지만 COUNT(*)COUNT(컬럼명)은 비슷해 보이지만 실제 의미와 동작 방식에서 중요한 차이를 가지고 있습니다.

COUNT(*)는 모든 행을 센다

COUNT(*)는 해당 테이블에서 NULL을 포함한 모든 행의 개수를 셉니다. 이는 테이블에 존재하는 전체 레코드 수를 파악하고자 할 때 사용됩니다.

예시:

SELECT COUNT(*) FROM employees;

이 쿼리는 employees 테이블의 총 행 수를 반환합니다. 특정 컬럼에 NULL이 있든 없든 관계없이 전체 행 수를 기준으로 계산합니다.

COUNT(컬럼명)는 NULL을 제외한다

반면 COUNT(컬럼명)은 해당 컬럼에서 NULL이 아닌 값의 개수만 셉니다. 즉, 어떤 컬럼의 값이 얼마나 채워져 있는지, 즉 실제 데이터가 있는 레코드 수를 알고 싶을 때 유용합니다.

예시:

SELECT COUNT(department_id) FROM employees;

이 쿼리는 department_id 컬럼의 값이 NULL이 아닌 행의 개수를 반환합니다. 만약 부서가 배정되지 않은 사원이 있다면 그 행은 집계에서 제외됩니다.

실무에서의 활용 팁

  • 데이터 완전성 검증 시에는 COUNT(컬럼명)을 사용하여 누락된 값이 있는지 파악합니다.
  • 전체 행 수가 필요한 로깅, 페이징 처리 등에서는 COUNT(*)을 사용하는 것이 적절합니다.
  • COUNT(DISTINCT 컬럼명)처럼 고유한 값의 개수를 세는 방식과도 구분하여 사용해야 합니다.

결론

COUNT(*)COUNT(컬럼명)은 비슷해 보이지만 전혀 다른 결과를 가져올 수 있으므로, 목적에 따라 정확히 구분하여 사용하는 것이 중요합니다. 특히 실무에서 NULL 값이 얼마나 존재하는지를 파악할 때 이 차이를 알고 있으면 보다 정확한 데이터 분석이 가능합니다.

#SQL #COUNT #집계함수 #기초정리 #데이터베이스 #NULL #쿼리

728x90
반응형
LIST

JOIN 없이도 가능하다? SQL에서 서브쿼리로 해결하는 3가지 실무 상황

Posted by heoncode
2025. 4. 11. 15:55 SQL 기초 정리
728x90
반응형
SMALL

SQL에서 데이터를 합치기 위해 가장 먼저 떠오르는 키워드는 JOIN입니다. 하지만 모든 상황에서 JOIN이 꼭 필요한 것은 아닙니다. 실무에서는 JOIN을 쓰기 복잡하거나 성능상 불리할 때, 서브쿼리(Subquery)를 이용해 문제를 해결하기도 합니다. 이번 글에서는 JOIN 없이 서브쿼리만으로 해결할 수 있는 3가지 실무 상황을 소개합니다.

1. 특정 조건에 해당하는 값만 가져올 때

예를 들어 각 사원의 부서 이름을 출력하고 싶은데, 특정 부서만 필터링하고 싶다면 JOIN 없이도 다음과 같이 서브쿼리로 처리할 수 있습니다.

SELECT emp_name,
       (SELECT dept_name
        FROM department d
        WHERE d.dept_id = e.dept_id)
       AS dept_name
FROM employee e
WHERE e.dept_id IN (10, 20);

JOIN을 사용하지 않고도 서브쿼리로 필요한 부서명을 함께 출력할 수 있습니다.

2. 조건 비교를 위해 필요한 보조 데이터를 가져올 때

각 제품의 가격이 전체 평균보다 높은 제품만 찾고 싶다면, 아래와 같이 서브쿼리를 WHERE 절에 활용할 수 있습니다.

SELECT product_name, price
FROM product
WHERE price > (SELECT AVG(price) FROM product);

이처럼 전체 집계 결과와 비교할 때도 서브쿼리를 사용하면 JOIN 없이 해결할 수 있습니다.

3. 최근 거래 내역 등 특정 조건의 1건만 가져올 때

각 고객의 최근 주문 내역을 보고 싶다면, 관련 테이블을 JOIN하기보다 상관 서브쿼리를 사용할 수 있습니다.

SELECT c.customer_id,
       (SELECT order_date
        FROM orders o
        WHERE o.customer_id = c.customer_id
        ORDER BY order_date DESC
        FETCH FIRST 1 ROW ONLY)
       AS latest_order
FROM customer c;

이 방식은 고객 수가 많아도 간결하고 효율적인 쿼리를 작성할 수 있게 해줍니다.


JOIN은 강력한 도구지만, 서브쿼리는 구조를 단순화하거나 불필요한 조인을 줄이는 데 유용하게 쓰일 수 있습니다. 실무에서는 복잡한 조인보다 오히려 서브쿼리로 명확하게 표현하는 것이 유지보수나 성능 측면에서 더 나은 선택이 되는 경우도 많습니다.

#SQL #서브쿼리 #JOIN #실무팁 #쿼리작성 #DB초보 #SQL기초

728x90
반응형
LIST

DISTINCT vs GROUP BY – 결과는 같아도 목적은 다르다

Posted by heoncode
2025. 4. 11. 11:20 SQL 기초 정리
728x90
반응형
SMALL

SQL에서 중복된 값을 제거하기 위해 DISTINCT를 사용하고, 데이터를 그룹화하기 위해 GROUP BY를 사용합니다. 하지만 때로는 두 문장이 같은 결과를 반환하기도 하여, 어떤 걸 써야 할지 혼란스러울 수 있습니다. 이 글에서는 두 구문의 차이를 명확하게 정리합니다.

DISTINCT: 단순히 중복된 행을 제거

DISTINCTSELECT 절에서 중복된 행을 제거하는 용도로 사용됩니다. 특정 컬럼 또는 여러 컬럼 조합이 중복일 경우, 하나만 남기고 제거합니다.

예시:

SELECT DISTINCT dept_id 
FROM employees;

→ 부서 ID가 중복되는 경우 하나만 표시됩니다.

여러 컬럼을 기준으로도 중복 제거가 가능합니다:

SELECT DISTINCT dept_id, job 
FROM employees;

→ 부서 ID와 직책 조합이 동일한 경우, 하나만 남깁니다.

GROUP BY: 데이터를 그룹으로 묶은 후 집계

GROUP BY데이터를 그룹화한 뒤, 집계 함수(SUM, COUNT 등)를 함께 사용할 때 주로 사용됩니다. 단순히 중복 제거가 목적이라면 DISTINCT가 더 적절하지만, 그룹별 통계가 필요하다면 GROUP BY를 사용해야 합니다.

예시:

SELECT dept_id, COUNT(*) 
FROM employees
GROUP BY dept_id;

→ 부서별로 몇 명의 직원이 있는지를 보여줍니다.

만약 집계 함수 없이 GROUP BY만 사용한다면 DISTINCT와 유사한 결과가 나오지만, 문장의 의미는 다릅니다.

예시:

SELECT dept_id 
FROM employees 
GROUP BY dept_id;

SELECT DISTINCT dept_id FROM employees;와 결과는 같지만, 의미상 그룹화입니다.


정리

목적 사용 구문
단순 중복 제거 DISTINCT
집계 또는 그룹 통계 GROUP BY

실무 팁: 결과만 보고 두 문장을 혼동하면 안 됩니다. 왜 이 구문을 쓰는지, 목적에 따라 구문을 선택하세요.


#SQL #DISTINCT #GROUPBY #중복제거 #집계함수 #기초정리 #실무팁 #데이터분석

728x90
반응형
LIST

WHERE 절과 HAVING 절, 헷갈리는 이유와 실무 기준 정리

Posted by heoncode
2025. 4. 11. 08:41 SQL 기초 정리
728x90
반응형
SMALL

SQL에서 조건을 설정할 수 있는 절은 대표적으로 WHEREHAVING이 있습니다. 둘 다 데이터를 필터링하는 기능이지만, 사용하는 시점과 용도에는 분명한 차이가 있습니다. 실무에서도 종종 이 둘을 혼용하거나, 쿼리가 잘못 동작하는 원인이 되기도 합니다.

WHERE 절: 집계 전 데이터를 필터링

WHERE 절은 그룹화나 집계가 수행되기 전에 데이터를 필터링합니다. 즉, 원본 테이블에서 조건을 걸고 필요한 행만 남긴 후에 GROUP BY, SUM, AVG 등의 집계 함수가 동작합니다.

예시:

SELECT dept_id, COUNT(*) 
FROM employees
WHERE job = 'MANAGER'
GROUP BY dept_id;

→ 여기서 WHERE은 "직책이 MANAGER인 직원"만 대상으로 그룹화합니다.

HAVING 절: 집계 이후 그룹 필터링

HAVING 절은 GROUP BY 이후 집계된 결과에 조건을 거는 데 사용합니다. WHERE과 달리 집계 함수(COUNT, SUM, 등)를 사용할 수 있습니다.

예시:

SELECT dept_id, COUNT(*) AS cnt
FROM employees
GROUP BY dept_id
HAVING COUNT(*) >= 5;

→ 모든 부서를 그룹화한 후, 직원 수가 5명 이상인 부서만 결과로 출력됩니다.

둘 다 쓰는 경우

두 절을 함께 쓰는 것도 가능합니다. 이때는 WHERE이 먼저, HAVING이 나중에 적용됩니다.

SELECT dept_id, COUNT(*) 
FROM employees
WHERE job = 'MANAGER'
GROUP BY dept_id
HAVING COUNT(*) >= 2;

→ MANAGER만 대상으로 부서별 그룹을 만들고, 그중에서 2명 이상인 부서만 필터링합니다.


실무 팁으로 기억하면 좋습니다:

  • WHERE은 개별 행을 필터링
  • HAVING은 집계 결과를 필터링

이 원칙만 기억하면 두 조건절을 헷갈릴 일이 줄어듭니다.


#SQL #WHERE절 #HAVING절 #조건절 #GROUPBY #집계함수 #기초정리 #실무팁

728x90
반응형
LIST

LEFT JOIN 결과가 예상과 다를 때? 누락된 데이터의 진짜 원인

Posted by heoncode
2025. 4. 11. 00:38 SQL 기초 정리
728x90
반응형
SMALL

SQL에서 LEFT JOIN왼쪽 테이블의 모든 데이터를 기준으로 오른쪽 테이블과 연결해주는 기능입니다. 하지만 실무에서는 종종 LEFT JOIN을 썼는데도 결과가 예상보다 적게 나오는 일이 발생합니다. 이 글에서는 그런 상황에서 확인해야 할 3가지 핵심 원인을 소개합니다.

1. WHERE 절 조건이 JOIN 결과를 제한한다

아래 쿼리를 살펴봅시다:

SELECT *
FROM employees e
LEFT JOIN departments d ON e.dept_id = d.id
WHERE d.location = 'SEOUL';

의도는 모든 직원 정보를 보고 싶은 것인데, 이 쿼리는 d.location이 NULL인 직원(=부서가 없는 직원)은 제외됩니다. 이는 WHERE 절이 조인 이후에 적용되기 때문입니다.

→ 해결책은 조건을 JOIN 안에 넣는 것입니다:

SELECT *
FROM employees e
LEFT JOIN departments d ON e.dept_id = d.id AND d.location = 'SEOUL';

이렇게 하면 부서가 없는 직원도 빠지지 않습니다.

2. JOIN 조건이 누락되거나 잘못되었다

SELECT *
FROM employees e
LEFT JOIN departments d ON e.name = d.name;

이런 식으로 정확한 조인 조건 없이 컬럼 이름만 같은 걸 기준으로 조인하면 원하지 않는 결과가 나옵니다. 항상 기본키-외래키 관계 또는 고유한 값을 기준으로 조인해야 합니다.

3. 중첩 JOIN과 서브쿼리에서 발생하는 필터링

복잡한 쿼리일수록 LEFT JOIN이 서브쿼리 내부에 있거나 INNER JOIN과 함께 쓰이면서 무의식적으로 결과가 줄어들 수 있습니다. 쿼리 구조를 항상 시각화하면서 데이터 흐름을 따져보는 습관이 필요합니다.


LEFT JOIN은 단순한 듯 보여도 실무에서는 자주 함정에 빠지는 구간입니다. 특히 WHERE 절의 위치나 조인 조건에 따라 결과가 확 달라질 수 있으니 항상 주의 깊게 쿼리를 작성해야 합니다.


#SQL #JOIN #LEFTJOIN #외부조인 #누락 #쿼리디버깅 #기초정리 #실무팁

728x90
반응형
LIST