SELECT 쿼리 안에 다른 SELECT 쿼리를 넣는 문법으로, 복잡한 조건을 한 번에 처리할 수 있게 해줍니다.
기본 예제: 평균보다 높은 사용금액 조회
-- 1단계: 평균 구하기
SELECT AVG(사용금액) FROM card; -- 결과: 245000
-- 2단계: 평균보다 높은 값 조회
SELECT * FROM card WHERE 사용금액 > 245000;
-- 서브쿼리로 한번에 처리
SELECT * FROM card WHERE 사용금액 >
(SELECT AVG(사용금액) FROM card);
( ) 괄호로 감싸야 함WHERE 절에서 사용
-- 평균 사용금액보다 높은 고객 조회
SELECT * FROM card
WHERE 사용금액 > (SELECT AVG(사용금액) FROM card);
SELECT 절에서 사용
-- 각 고객의 사용금액과 평균 사용금액 함께 출력
SELECT 고객명, 사용금액, (SELECT AVG(사용금액) FROM card) AS 평균금액
FROM card;
-- 평균과의 차이 계산
SELECT 고객명, 사용금액,
사용금액 - (SELECT AVG(사용금액) FROM card) AS 평균대비차이
FROM card;
IN 절에서 사용
-- 블랙리스트 테이블 생성 후 해당 고객들의 사용금액 조회
SELECT 사용금액 FROM card
WHERE 고객명 IN (SELECT 이름 FROM blacklist);
-- 고객등급이 '패밀리'인 사람들의 평균 연체횟수보다 연체횟수가 높은 사람 수
SELECT COUNT(*) FROM card
WHERE 연체횟수 > (
SELECT AVG(연체횟수) FROM card WHERE 고객등급 = '패밀리'
);
같은 값을 가진 행들을 그룹으로 묶어서 집계 함수를 적용할 때 사용합니다.
-- 고객등급별로 그룹화
SELECT 고객등급 FROM card GROUP BY 고객등급;
-- 고객등급별 고객 수 계산
SELECT 고객등급, COUNT(고객명) FROM card GROUP BY 고객등급;
-- 고객등급별 평균 사용금액
SELECT 고객등급, AVG(사용금액) FROM card GROUP BY 고객등급;
-- 고객등급별 다양한 통계
SELECT 고객등급,
COUNT(*) AS 고객수,
AVG(사용금액) AS 평균사용금액,
MAX(사용금액) AS 최대사용금액,
MIN(사용금액) AS 최소사용금액,
SUM(사용금액) AS 총사용금액
FROM card
GROUP BY 고객등급;
GROUP BY로 그룹화된 결과를 필터링할 때 사용합니다.
-- 고객 수가 2명 이상인 등급만 조회
SELECT 고객등급, COUNT(*) AS 고객수
FROM card
GROUP BY 고객등급
HAVING COUNT(*) >= 2;
-- VIP 등급만 필터링
SELECT 고객등급, COUNT(고객명) FROM card
GROUP BY 고객등급
HAVING 고객등급 = 'vip';
-- WHERE와 HAVING 함께 사용
SELECT 고객등급, COUNT(고객명) FROM card
WHERE 연체횟수 = 0 -- 원본 데이터 필터링
GROUP BY 고객등급
HAVING 고객등급 = 'vip'; -- 그룹화 결과 필터링
SELECT 고객등급, AVG(사용금액) -- 5. 최종 결과 선택
FROM card -- 1. 테이블 선택
WHERE 연체횟수 = 0 -- 2. 원본 데이터 필터링
GROUP BY 고객등급 -- 3. 그룹화
HAVING AVG(사용금액) > 200000 -- 4. 그룹 결과 필터링
ORDER BY 고객등급; -- 6. 정렬
두 가지 경우만 처리할 때 사용하는 간단한 조건문입니다.
-- 기본 문법
IF(조건식, 조건이_참일때_값, 조건이_거짓일때_값)
-- 사용금액이 20만원 이상이면 '우수', 미만이면 '거지'
SELECT 고객명, 사용금액,
IF(사용금액 > 200000, '우수', '거지') AS 등급
FROM card;
-- 연체 여부 확인
SELECT 고객명, 연체횟수,
IF(연체횟수 = 0, '정상', '연체') AS 상태
FROM card;
세 가지 이상의 경우를 처리할 때 사용하는 확장된 조건문입니다.
-- 기본 문법
CASE
WHEN 조건식1 THEN 값1
WHEN 조건식2 THEN 값2
WHEN 조건식3 THEN 값3
ELSE 기본값
END
-- 사용금액에 따른 등급 분류
SELECT 고객명, 사용금액,
CASE
WHEN 사용금액 >= 300000 THEN 'vip'
WHEN 사용금액 >= 200000 THEN '로열'
WHEN 사용금액 >= 100000 THEN '준수'
ELSE '그지'
END AS 신규등급
FROM card;
-- 등급별 점수 합계 (vip=3점, 로열=2점, 패밀리=1점)
SELECT SUM(
CASE
WHEN 고객등급 = 'vip' THEN 3
WHEN 고객등급 = '로열' THEN 2
ELSE 1
END
) AS 총점수
FROM card;
-- 조건별 집계
SELECT
SUM(CASE WHEN 사용금액 >= 300000 THEN 1 ELSE 0 END) AS 고액고객수,
SUM(CASE WHEN 연체횟수 > 0 THEN 1 ELSE 0 END) AS 연체고객수
FROM card;
사용금액 30만원 이상은 50% 증액, 미만은 10% 증액하여 총합 계산
SELECT SUM(
CASE
WHEN 사용금액 >= 300000 THEN 사용금액 * 1.5
ELSE 사용금액 * 1.1
END
) AS 조작된총합
FROM card;
현재 등급과 새로운 등급 기준이 다른 고객들만 조회
SELECT 고객명, 사용금액, 고객등급,
CASE
WHEN 사용금액 >= 300000 THEN 'vip'
WHEN 사용금액 >= 200000 THEN '로열'
ELSE '패밀리'
END AS 신규등급
FROM card
WHERE 고객등급 != CASE
WHEN 사용금액 >= 300000 THEN 'vip'
WHEN 사용금액 >= 200000 THEN '로열'
ELSE '패밀리'
END;
-- 연체횟수별 고객 수 (1명인 경우 제외)
SELECT 연체횟수, COUNT(*) AS 고객수
FROM card
GROUP BY 연체횟수
HAVING COUNT(*) > 1
ORDER BY 연체횟수;
-- 등급별 최대/최소 사용금액 비율
SELECT 고객등급,
MAX(사용금액) AS 최대금액,
MIN(사용금액) AS 최소금액,
ROUND(MAX(사용금액) / MIN(사용금액), 2) AS 격차비율
FROM card
GROUP BY 고객등급
ORDER BY 고객등급;
-- 비효율적: 매번 서브쿼리 실행
SELECT *, (SELECT AVG(사용금액) FROM card) FROM card;
-- 효율적: 변수나 임시 테이블 활용 고려
-- (실제로는 대부분의 DBMS가 자동 최적화)
-- 등급별 평균 사용금액을 높은 순으로 정렬
SELECT 고객등급, AVG(사용금액) AS 평균사용금액
FROM card
GROUP BY 고객등급
ORDER BY 평균사용금액 DESC;
-- 여러 컬럼을 고려한 등급 산정
SELECT 고객명,
CASE
WHEN 사용금액 >= 300000 AND 연체횟수 = 0 THEN 'VIP'
WHEN 사용금액 >= 200000 AND 연체횟수 <= 1 THEN '우수'
WHEN 연체횟수 > 3 THEN '주의'
ELSE '일반'
END AS 종합등급
FROM card;
이러한 기능들을 조합하면 복잡한 비즈니스 로직을 SQL로 구현할 수 있으며, 데이터 분석과 보고서 작성에 매우 유용합니다.