원칙 3 — WHERE
원칙 3 — WHERE
어떤 행만 볼까? 내가 원하는 조건의 자료만 추출하고 싶다.
박지수 팀장 : 민서씨, 이번엔 VIP 고객만 뽑아줄 수 있어요? 이번 달 특별 혜택 대상자 명단인데, 전체 고객 말고 VIP만 필요해요.
김민서 사원 : 아, 엑셀로 VIP를 걸러내면 되지 않을까요?
박지수 팀장 : 그렇게 하면 VIP을 걸러낼수 있지만 번거로울수 있죠? 행 자체를 없애는 구문은 WHERE을 써야 해요.
핵심 차이가 여기 있습니다.
엑셀— 쉽게 변경은 가능하지만 큰 데이터에 대해서는 오래걸리거 파일이 열리지 않을 수 있다.WHERE— 데이터 크기와 상관없이 조건에 맞지 않는 행 자체를 없앤다.
원칙 1에서는 테이블을 다뤘습니다. 원칙 2에서는 열을 다뤘습니다. 원칙 3에서는 행을 다룹니다. 이 세가지를 잘 다루면 일단 반은 먹고 들어가는 겁니다.
이런 결과를 원할 때
전체 고객 중 VIP만
| 이름 | 나이 | 등급 |
|---|---|---|
| 김민수 | 28 | VIP |
| 박서연 | NULL | VIP |
| 강도윤 | 33 | VIP |
단가가 500,000원 이상인 판매 내역만
| 상품명 | 단가 |
|---|---|
| 노트북 Pro | 1,500,000 |
| 노트북 Air | 1,200,000 |
| 모니터 32인치 | 550,000 |
| 노트북 Pro | 1,500,000 |
| 노트북 Air | 1,200,000 |
이 두 가지를 수헹하는 것이 이번 챕터의 목표입니다.
WHERE가 하는 일
WHERE는 조건에 맞는 행만 결과에 남기는 명령어입니다.
SELECT 열이름
FROM 테이블이름
WHERE 조건;
조건을 만족하는 행만 결과에 나옵니다. 만족하지 않는 행은 결과에서 사라집니다.
💡 머릿속으로 생각하는 순서
어느 테이블에서? → FROM
어떤 행만? → WHERE
어떤 열을? → SELECT
코드 작성 순서는 SELECT → FROM → WHERE지만 머릿속 순서는 FROM → WHERE → SELECT입니다. 결과를 먼저 그릴 때 이 순서로 생각하면 훨씬 자연스럽습니다.
STEP 1 — 같은 값인 행만 남기자
가장 기본적인 조건입니다. 특정 값과 정확히 같은 행만 남깁니다.
SELECT 이름, 나이, 등급
FROM 고객정보
WHERE 등급 = 'VIP';
실행 결과
| 이름 | 나이 | 등급 |
|---|---|---|
| 김민수 | 28 | VIP |
| 박서연 | NULL | VIP |
| 강도윤 | 33 | VIP |
10명에서 VIP 3명만 남았습니다.
문자 값은 작은따옴표로 감쌉니다. 숫자는 따옴표 없이 씁니다.
-- 문자 값
WHERE 등급 = 'VIP'
WHERE 지역 = '서울'
-- 숫자 값
WHERE 나이 = 30
WHERE 단가 = 45000
STEP 2 — 범위 조건으로 행을 남기자
크다, 작다, 이상, 이하 같은 범위 조건을 쓸 수 있습니다.
SELECT 이름, 나이
FROM 고객정보
WHERE 나이 >= 30;
실행 결과
| 이름 | 나이 |
|---|---|
| 이지은 | 35 |
| 최준호 | 41 |
| 강도윤 | 33 |
| 한예진 | 45 |
| 오태양 | 31 |
30세 이상인 고객 5명만 남았습니다.
비교 연산자는 여섯 가지입니다.
| 연산자 | 의미 | 예시 |
|---|---|---|
| = | 같다 | WHERE 등급 = 'VIP' |
| != | 같지 않다 | WHERE 지역 != '서울' |
| > | 크다 (초과) | WHERE 나이 > 30 |
| < | 작다 (미만) | WHERE 단가 < 50000 |
| >= | 크거나 같다 (이상) | WHERE 나이 >= 30 |
| <= | 작거나 같다 (이하) | WHERE 단가 <= 550000 |
판매정보 테이블에서도 써봅니다.
SELECT 상품명, 단가
FROM 판매정보
WHERE 단가 >= 500000;
실행 결과
| 상품명 | 단가 |
|---|---|
| 노트북 Pro | 1,500,000 |
| 노트북 Air | 1,200,000 |
| 모니터 32인치 | 550,000 |
| 노트북 Pro | 1,500,000 |
| 노트북 Air | 1,200,000 |
12건에서 5건만 남았습니다.
STEP 3 — 조건 두 개를 동시에 쓰자
조건을 하나만 쓰는 경우보다 두 개 이상 조합하는 경우가 훨씬 많습니다.
AND와 OR로 조건을 연결합니다.
AND— 두 조건을 모두 만족하는 행만OR— 두 조건 중 하나라도 만족하는 행만
SELECT 이름, 나이, 등급
FROM 고객정보
WHERE 등급 = 'VIP'
AND 나이 >= 30;
실행 결과
| 이름 | 나이 | 등급 |
|---|---|---|
| 강도윤 | 33 | VIP |
VIP이면서 동시에 30세 이상인 사람만 남습니다.
SELECT 이름, 나이, 등급
FROM 고객정보
WHERE 등급 = 'VIP'
OR 등급 = '프리미엄';
실행 결과
| 이름 | 나이 | 등급 |
|---|---|---|
| 김민수 | 28 | VIP |
| 박서연 | NULL | VIP |
| 정하윤 | 29 | 프리미엄 |
| 강도윤 | 33 | VIP |
| 임수아 | NULL | 프리미엄 |
VIP이거나 프리미엄인 사람이 모두 나옵니다. 일반과 NULL인 고객만 제외됩니다.
💡 AND와 OR 선택 기준
- 조건을 좁히고 싶다 →
AND(결과가 줄어듦) - 조건을 넓히고 싶다 →
OR(결과가 늘어남)
STEP 4 — 여러 값 중 하나인 행만 남기자
OR를 여러 번 쓰면 코드가 길어집니다.
IN을 쓰면 같은 결과를 훨씬 깔끔하게 쓸 수 있습니다.
-- OR로 쓰면 길다
WHERE 등급 = 'VIP' OR 등급 = '프리미엄'
-- IN으로 쓰면 짧다
WHERE 등급 IN ('VIP', '프리미엄')
SELECT 이름, 나이, 등급
FROM 고객정보
WHERE 등급 IN ('VIP', '프리미엄');
실행 결과
| 이름 | 나이 | 등급 |
|---|---|---|
| 김민수 | 28 | VIP |
| 박서연 | NULL | VIP |
| 정하윤 | 29 | 프리미엄 |
| 강도윤 | 33 | VIP |
| 임수아 | NULL | 프리미엄 |
값의 종류가 많을수록 IN이 훨씬 유리합니다.
반대로 특정 값을 제외하고 싶을 때는 NOT IN을 씁니다.
SELECT 이름, 나이, 등급
FROM 고객정보
WHERE 등급 NOT IN ('VIP', '프리미엄');
실행 결과
| 이름 | 나이 | 등급 |
|---|---|---|
| 이지은 | 35 | 일반 |
| 윤서준 | 27 | 일반 |
| 오태양 | 31 | 일반 |
VIP와 프리미엄을 제외한 나머지가 나옵니다.
STEP 5 — 범위 안에 있는 행만 남기자
나이가 25세에서 35세 사이인 사람만 보고 싶다면 비교 연산자 두 개를 AND로 연결할 수 있습니다.
-- 방법 1: AND로 연결
WHERE 나이 >= 25 AND 나이 <= 35
-- 방법 2: BETWEEN 사용
WHERE 나이 BETWEEN 25 AND 35
SELECT 이름, 나이, 등급
FROM 고객정보
WHERE 나이 BETWEEN 25 AND 35;
실행 결과
| 이름 | 나이 | 등급 |
|---|---|---|
| 김민수 | 28 | VIP |
| 이지은 | 35 | 일반 |
| 정하윤 | 29 | 프리미엄 |
| 강도윤 | 33 | VIP |
| 윤서준 | 27 | 일반 |
| 오태양 | 31 | 일반 |
25세 이상 35세 이하인 6명이 나왔습니다.
⚠ BETWEEN A AND B는 A 이상 B 이하입니다. A와 B 자체도 포함됩니다.
BETWEEN은 단가에도 쓸 수 있습니다.
SELECT 상품명, 단가
FROM 판매정보
WHERE 단가 BETWEEN 45000 AND 550000;
실행 결과
| 상품명 | 단가 |
|---|---|
| 무선 키보드 | 45,000 |
| 모니터 27인치 | 350,000 |
| 모니터 32인치 | 550,000 |
| 무선 키보드 | 45,000 |
| 웹캠 HD | 89,000 |
STEP 6 — 글자 패턴으로 행을 찾자
정확한 값이 아니라 글자 패턴으로 찾고 싶을 때는 LIKE를 씁니다.
기호 의미
%: 어떤 글자든, 몇 글자든_: 딱 한 글자
-- '노'로 시작하는 상품
SELECT 상품명, 단가
FROM 판매정보
WHERE 상품명 LIKE '노%';
-- '허브'로 끝나는 상품
SELECT 상품명, 단가
FROM 판매정보
WHERE 상품명 LIKE '%허브';
-- '모니터'가 들어가는 상품
SELECT 상품명, 단가
FROM 판매정보
WHERE 상품명 LIKE '%모니터%';
실행 결과
| 상품명 | 단가 |
|---|---|
| 노트북 Pro | 1,500,000 |
| 노트북 Air | 1,200,000 |
| 노트북 Pro | 1,500,000 |
| 노트북 Air | 1,200,000 |
| 상품명 | 단가 |
|---|---|
| USB 허브 | 25,000 |
| 상품명 | 단가 |
|---|---|
| 모니터 27인치 | 350,000 |
| 모니터 32인치 | 550,000 |
STEP 7 — 비어있는 행을 찾자
데이터가 없는 칸, 즉 비어있는 값을 NULL이라고 합니다. NULL은 일반 비교 연산자로 찾을 수 없습니다.
-- ❌ 이렇게 하면 찾을 수 없습니다
WHERE 지역 = NULL
-- ✅ NULL은 IS NULL로 찾습니다
WHERE 지역 IS NULL
NULL은 비교 연산자(=, !=)로 찾을 수 없습니다.
반드시 IS NULL, IS NOT NULL을 씁니다.
자주 하는 실수
- 실수 1 — 문자 값에 따옴표를 빠뜨린다
-- ❌ 따옴표가 없어서 에러
WHERE 등급 = VIP
-- ✅ 문자 값은 작은따옴표로
WHERE 등급 = 'VIP'
에러 메시지: Unknown column 'VIP' in 'where clause'
SQL이 VIP를 열 이름으로 인식합니다.
- 실수 2 —
AND와OR를 동시에 쓸 때 괄호를 빠뜨린다
-- ❌ 의도와 다른 결과가 나올 수 있습니다
WHERE 등급 = 'VIP' OR 등급 = '프리미엄' AND 나이 >= 30
-- ✅ 괄호로 의도를 명확하게
WHERE (등급 = 'VIP' OR 등급 = '프리미엄') AND 나이 >= 30
AND와 OR를 함께 쓸 때는 괄호로 묶어서 의도를 명확하게 합니다.
- 실수 3 —
NULL을=로 비교한다
-- ❌ 결과가 항상 비어있습니다
WHERE 지역 = NULL
-- ✅ NULL은 IS NULL로
WHERE 지역 IS NULL
개념 정리
| 기능 | 코드 | 예시 |
|---|---|---|
| 같은 값 | = | WHERE 등급 = 'VIP' |
| 다른 값 | != | WHERE 지역 != '서울' |
| 범위 | <, >, <=, >= | WHERE 나이 >= 30 |
| 여러 값 중 하나 | IN | WHERE 등급 IN ('VIP', '프리미엄') |
| 범위 안 | BETWEEN A AND B | WHERE 나이 BETWEEN 25 AND 35 |
| 패턴 검색 | LIKE | WHERE 상품명 LIKE '%모니터%' |
| 비어있는 값 | IS NULL | WHERE 지역 IS NULL |
| 조건 연결 | AND / OR | WHERE 등급 = 'VIP' AND 나이 >= 30 |
연습문제
이번 챕터에서 배운 것만 씁니다. ORDER BY, GROUP BY는 아직 쓰지 않습니다.
Q1. ★☆☆ 고객정보 테이블에서 지역이 서울인 고객의 이름과 등급을 조회하세요.
Q2. ★★☆ 판매정보 테이블에서 단가가 500,000원 이상이고 상품명에 '노트북'이 들어가는 판매 내역의 상품명과 단가를 조회하세요.
Q3. ★★★ 고객정보 테이블에서 VIP 또는 프리미엄 등급이면서 나이가 25세 이상 35세 이하인 고객의 이름, 나이, 등급을 조회하세요.
정답 및 해설
Q1 정답
SELECT 이름, 등급
FROM 고객정보
WHERE 지역 = '서울';
실행 결과
| 이름 | 등급 |
|---|---|
| 김민수 | VIP |
| 박서연 | VIP |
| 정하윤 | 프리미엄 |
| 임수아 | 프리미엄 |
Q2 정답
SELECT 상품명, 단가
FROM 판매정보
WHERE 단가 >= 500000
AND 상품명 LIKE '%노트북%';
실행 결과
| 상품명 | 단가 |
|---|---|
| 노트북 Pro | 1,500,000 |
| 노트북 Air | 1,200,000 |
| 노트북 Pro | 1,500,000 |
| 노트북 Air | 1,200,000 |
두 조건을 AND로 연결했습니다.
단가가 500,000원 이상이면서 동시에 상품명에 '노트북'이 들어가는 판매 내역만 남습니다.
Q3 정답
SELECT 이름, 나이, 등급
FROM 고객정보
WHERE 등급 IN ('VIP', '프리미엄')
AND 나이 BETWEEN 25 AND 35;
실행 결과
| 이름 | 나이 | 등급 |
|---|---|---|
| 김민수 | 28 | VIP |
| 정하윤 | 29 | 프리미엄 |
| 강도윤 | 33 | VIP |
VIP 또는 프리미엄이면서 25세 이상 35세 이하인 3명입니다.
IN으로 여러 값을 한 번에 처리하고, BETWEEN으로 범위를 깔끔하게 표현했습니다.
두 조건은 AND로 연결해 모두 만족하는 행만 남겼습니다.
실무 패턴
패턴 1 — 기간 데이터 필터링
날짜 데이터를 범위로 자를 때 자주 씁니다.
SELECT 상품명, 단가, 판매일
FROM 판매정보
WHERE 판매일 BETWEEN '2024-01-01' AND '2024-01-31';
특정 월의 데이터만 뽑을 때 이 패턴을 씁니다.
패턴 2 — 조건 조합으로 타겟 추출
마케팅 대상자처럼 여러 조건을 동시에 만족하는 행을 뽑을 때 씁니다.
SELECT 이름, 나이, 등급
FROM 고객정보
WHERE 등급 IN ('VIP', '프리미엄')
AND 나이 BETWEEN 25 AND 45
AND 지역 = '서울';
조건이 많아질수록 WHERE 아래에 AND로 한 줄씩 추가하면 읽기 쉽고 수정하기도 쉽습니다.
김민서 사원
팀장님! VIP 고객만 딱 뽑혔어요. AND랑 OR 조합하니까 원하는 대로 좁혀지는 게 신기해요.
박지수 팀장
잘 했어요. 이제 SELECT로 열을 고르고, WHERE로 행을 걸러낼 수 있게 됐네요. 그런데 민서씨, 이 결과를 단가 높은 순으로 정렬하고 싶다면요?
김민서 사원 : 아... 그건 아직 모르는 거네요.
박지수 팀장 : 그게 다음 원칙이에요. 순서를 정하는 것, ORDER BY입니다.
▶ 원칙 3 — ORDER BY : 어떤 순서로 볼까