WHERE 로 걸러내기
비교·논리 연산자와 BETWEEN · IN · LIKE 로 원하는 행만 남깁니다. 괄호를 빠뜨렸을 때와 NULL 이 조건에서 빠지는 것도 봅니다.
어느 행을 남길지 정합니다
1.5 의 SELECT 가 어느 열을 낼지 정했다면,
WHERE 는 어느 행을 남길지 정합니다.
조건이 참인 행만 결과에 들어갑니다.
실습 데이터의 글은 507개입니다. 조건 없이 조회하면 507행이 모두 나오므로, 이제부터는
WHERE 로 볼 만큼만 남깁니다.
비교하기
조회수가 480 이상인 글만 남겨 봅니다.
SELECT TOP 4 num, title, hit_count FROM Board.POSTS WHERE hit_count >= 480 ORDER BY num;
| num | title | hit_count |
|---|---|---|
| 69 | 뷰 실무에서 겪은 일 | 483 |
| 70 | 제약 조건 실무에서 겪은 일 | 490 |
| 71 | 외래 키 실무에서 겪은 일 | 497 |
| 140 | 인덱스 예제 모음 | 480 |
| 연산자 | 뜻 |
|---|---|
| = | 같다 |
| <> | 같지 않다. != 로 적어도 되지만 <> 가 표준입니다 |
| > < | 크다 · 작다 |
| >= <= | 크거나 같다 · 작거나 같다 |
글자도 비교할 수 있습니다. code = 'free' 처럼 적으면 됩니다.
대소문자를 가리는지는 데이터베이스 설정을 따릅니다 — 실습
데이터베이스는 가리지 않으므로 'FREE' 로 적어도 찾아집니다.
조건 여러 개 — AND 와 OR
AND 는 둘 다 참일 때, OR 는
하나만 참이어도 남깁니다.
SELECT TOP 4 num, board_num, hit_count, title FROM Board.POSTS WHERE board_num = 3 AND hit_count >= 400 ORDER BY num;
| num | board_num | hit_count | title |
|---|---|---|---|
| 58 | 3 | 406 | 전문 검색 이렇게 쓰는 게 맞나요 |
| 59 | 3 | 413 | 계산 열 이렇게 쓰는 게 맞나요 |
| 67 | 3 | 469 | 커서 실무에서 겪은 일 |
| 68 | 3 | 476 | 임시 테이블 실무에서 겪은 일 |
괄호를 빠뜨리면 — AND 가 먼저 묶입니다
이 자리가 실무에서 가장 자주 어긋납니다. "공지 또는 자유게시판의 글 가운데 조회수 400 이상" 을 그대로 옮겨 적으면 뜻이 달라집니다.
-- 괄호 없이 — AND 가 먼저 묶입니다 SELECT COUNT(*) AS 괄호없음 FROM Board.POSTS WHERE board_num = 1 OR board_num = 2 AND hit_count >= 400; -- 뜻한 대로 — 괄호로 묶습니다 SELECT COUNT(*) AS 괄호있음 FROM Board.POSTS WHERE (board_num = 1 OR board_num = 2) AND hit_count >= 400;
| 괄호없음 |
|---|
| 74 |
| 괄호있음 |
|---|
| 47 |
27건이 차이 납니다. 괄호가 없으면
AND 가 먼저 묶여 이렇게 읽힙니다.
board_num = 1 OR (board_num = 2 AND hit_count >= 400)
즉 공지사항은 조회수와 무관하게 모두 들어옵니다. 오류가 나지 않고 결과만 조용히 달라지므로, 세어 보기 전에는 알아채기 어렵습니다.
OR 를 섞을 때는 괄호를 두십시오.
없어도 되는 자리에 넣는 것이 잘못된 결과를 내는 것보다 낫습니다.
COUNT(*) 는 남은 행이 몇 개인지 세는 함수입니다. 여기서는
건수를 비교하려고 사용했고, 집계는 2.2 에서 다룹니다.
범위와 목록 — BETWEEN, IN
BETWEEN 은 범위를 적는 짧은 방법입니다.
양쪽 끝을 포함합니다.
SELECT COUNT(*) AS between_cnt FROM Board.POSTS WHERE hit_count BETWEEN 100 AND 200; -- 위와 같은 뜻입니다 -- WHERE hit_count >= 100 AND hit_count <= 200
| between_cnt |
|---|
| 122 |
날짜에 사용할 때는 조심하십시오.
BETWEEN '2026-01-01' AND '2026-01-31' 은 1월 31일
00:00:00 까지만 포함해, 그날 낮에 작성한 글이 빠집니다.
날짜는 >= 시작 AND < 다음날 로 적는 편이 안전합니다.
IN 은 여러 값 가운데 하나와 같은지 봅니다.
OR 를 늘어놓는 것보다 짧고 읽기 좋습니다.
SELECT num, code, name FROM Board.BOARDS WHERE code IN ('free', 'qna');
| num | code | name |
|---|---|---|
| 2 | free | 자유게시판 |
| 3 | qna | 질문답변 |
비슷한 글자 찾기 — LIKE
글자의 일부만 알 때 사용합니다. 두 가지 기호가 있습니다.
| 기호 | 뜻 | 보기 |
|---|---|---|
| % | 글자가 몇 개든(없어도 됩니다) | N'인덱스%' |
| _ | 글자 하나 | 'ho__' |
SELECT TOP 4 num, title FROM Board.POSTS WHERE title LIKE N'인덱스%' ORDER BY num;
| num | title |
|---|---|
| 20 | 인덱스 정리해 봤습니다 |
| 40 | 인덱스 이렇게 쓰는 게 맞나요 |
| 60 | 인덱스 실무에서 겪은 일 |
| 80 | 인덱스 초보자가 자주 하는 실수 |
앞뒤로 % 를 붙이면 가운데 어디에 있어도 찾습니다.
LIKE N'%정리%' 는 58건을 찾아냅니다.
앞에 % 를 붙이면 인덱스를 사용하지 못합니다. 앞부분을 알아야 인덱스에서 자리를 좁힐 수 있기 때문입니다. 글이 수십만 건이 되면 이 조회가 느려지고, 그때는 전문 검색(5.8)으로 옮겨야 합니다. 까닭은 5.4 에서 다룹니다.
NULL 은 = 로 비교할 수 없습니다
값이 없는 행을 찾으려고 = NULL 이라고 적으면
한 건도 나오지 않습니다. 오류도 나지 않습니다.
SELECT COUNT(*) AS eq_null FROM Member.USERS WHERE email = NULL; SELECT COUNT(*) AS is_null FROM Member.USERS WHERE email IS NULL;
| eq_null |
|---|
| 0 |
| is_null |
|---|
| 4 |
NULL 은 모르는 값이라 무엇과도 같지 않고,
자기 자신과도 같지 않습니다. 그래서 IS NULL ·
IS NOT NULL 이라는 전용 문법이 따로 있습니다.
같지 않다로 걸러도 NULL 은 빠집니다
더 걸리기 쉬운 자리가 있습니다. "홍길동의 주소가 아닌 회원" 을 세어 보면 19가 아니라 15 가 나옵니다.
SELECT COUNT(*) AS not_hong FROM Member.USERS WHERE email <> 'hong@example.com'; SELECT COUNT(*) AS total FROM Member.USERS;
| not_hong |
|---|
| 15 |
| total |
|---|
| 20 |
20명에서 홍길동 한 명을 뺀 19가 아닙니다. 전자 메일이 없는 회원 네 명이 함께 빠졌습니다. 모르는 값이 홍길동의 주소와 같은지 다른지도 알 수 없으므로 조건이 참이 되지 못한 것입니다.
그들까지 넣으려면 조건을 하나 더 적어야 합니다.
WHERE email <> 'hong@example.com' OR email IS NULL
값이 없을 수 있는 열을 조건에 넣을 때마다 이 점을 떠올리십시오. NULL 은 1.9 에서 한 단원을 들여 다시 다룹니다.
직접 해보기
자유게시판(board_num = 2)의 글 가운데 답글이 아닌 것, 즉 depth 가 0 인 것만 세어 보세요.
"자유게시판이나 질문답변의 글 가운데 조회수가 100 미만인 것" 을 찾는 문장을 적어 보세요. 괄호를 빼면 몇 건이 되는지도 비교해 보십시오.
WHERE는 어느 행을 남길지 정합니다. 조건이 참인 행만 나옵니다.AND가OR보다 먼저 묶입니다. 섞어 사용할 때는 괄호를 두십시오.BETWEEN은 양쪽 끝을 포함합니다. 날짜에는 조심해서 사용하십시오.LIKE의 % 를 앞에 붙이면 인덱스를 사용하지 못합니다.= NULL은 한 건도 찾지 못합니다.IS NULL을 사용하십시오.<>로 걸러도 NULL 인 행은 빠집니다. 넣으려면OR ... IS NULL을 더합니다.