•
WHERE절로 원하는 행만 골라낼 수 있다.
•
BETWEEN · IN · LIKE · IS NULL 네 가지 SQL 연산자를 상황에 맞게 쓸 수 있다.
•
LIKE의 와일드카드 % 와 _ 의 차이를 알고 결과를 예측할 수 있다.
•
AND가 OR보다 우선순위가 높다는 것을 알고 괄호를 올바르게 쓸 수 있다.
•
NOT IN 목록에 NULL이 있으면 결과가 0건이 되는 이유를 설명할 수 있다.
1. WHERE절의 역할
1) 행을 걸러내는 필터
SELECT 컬럼명 -- ⑤ 어떤 컬럼을 볼지
FROM 테이블명 -- ① 어느 테이블에서
WHERE 조건식; -- ② 어떤 행만 남길지 ← 오늘의 주제
SQL
복사
-- ============================================================
-- 【이해용 예제】 조건을 붙이면 결과가 어떻게 줄어드는가
-- ============================================================
-- (1) 조건 없이 전체 조회
SELECT ENAME, DEPTNO, SAL
FROM EMP; -- WHERE 가 없으면 모든 행이 나온다
-- → 14건
-- (2) 부서번호가 20인 사원만
SELECT ENAME, DEPTNO, SAL
FROM EMP
WHERE DEPTNO = 20; -- DEPTNO 값이 20인 행만 통과
-- ENAME DEPTNO SAL
-- ----- ------ -----
-- SMITH 20 800
-- JONES 20 2975
-- SCOTT 20 3000
-- ADAMS 20 1100
-- FORD 20 3000 → 5건
-- (3) 조건을 더 붙이면 더 줄어든다
SELECT ENAME, DEPTNO, SAL
FROM EMP
WHERE DEPTNO = 20 -- 조건 ①
AND SAL >= 3000; -- 조건 ② (AND 로 연결 → 둘 다 만족해야 함)
-- ENAME DEPTNO SAL
-- ----- ------ -----
-- SCOTT 20 3000
-- FORD 20 3000 → 2건
SQL
복사
2. 비교 연산자
1) 종류
연산자 | 의미 | 예 |
= | 같다 | DEPTNO = 20 |
> | 크다 | SAL > 3000 |
>= | 크거나 같다 | SAL >= 3000 |
< | 작다 | SAL < 1000 |
<= | 작거나 같다 | SAL <= 1000 |
<> != ^= | 같지 않다 (셋 다 동일) ![]() | JOB <> 'CLERK' |
시험 포인트: <> != ^= 는 완전히 같은 의미입니다.
표준 SQL 표기는 <> 이며, Oracle에서는 셋 다 동작합니다.2) 문자·날짜 비교 시 주의점
-- ============================================================
-- 【시험용 예제】 문자와 날짜를 비교할 때의 함정 ★
-- ============================================================
-- ⚠️ 함정 ① 문자열은 대소문자를 구분한다 (07강 회수)
SELECT ENAME FROM EMP WHERE ENAME = 'smith';
-- → 0건! 실제 저장된 값은 'SMITH' 이다
SELECT ENAME FROM EMP WHERE ENAME = 'SMITH';
-- ENAME
-- -----
-- SMITH → 1건 ✅
-- ⚠️ 함정 ② 문자는 '사전 순'으로 비교된다
SELECT ENAME FROM EMP WHERE ENAME > 'M';
-- → 'M' 보다 사전 순으로 뒤에 오는 이름들 (SMITH, WARD, TURNER, SCOTT …)
-- 숫자처럼 크기를 비교하는 게 아니라 '가나다/ABC 순서'로 비교한다
-- ⚠️ 함정 ③ 날짜를 문자열로 비교하면 DB 설정에 의존한다
SELECT ENAME, HIREDATE FROM EMP WHERE HIREDATE >= '1981-01-01';
-- → 실행하는 DB의 날짜 형식(NLS_DATE_FORMAT) 설정에 따라
-- 정상 동작할 수도, ORA-01861 오류가 날 수도 있다 ⚠️
-- ✅ 안전한 방법: TO_DATE 로 명시적 변환 (10강에서 자세히)
SELECT ENAME, HIREDATE FROM EMP WHERE HIREDATE >= TO_DATE('1981-01-01','YYYY-MM-DD');
-- ENAME HIREDATE
-- ------ ----------
-- ALLEN 1981-02-20
-- WARD 1981-02-22
-- ...
-- ⭐ 실무·시험 모두 '날짜는 TO_DATE 로 명시적 변환' 이 원칙이다.
SQL
복사
3. SQL 연산자 4종 

1) 한눈에 비교
연산자 | 의미 | 같은 뜻의 표현 |
BETWEEN A AND B | A 이상 B 이하 (경계값 포함) ![]() | >= A AND <= B |
IN (값1, 값2, …) | 목록 중 하나와 일치 | = 값1 OR = 값2 OR … |
LIKE '패턴' | 패턴과 일치 (부분 검색) | — |
IS NULL | NULL인지 확인 | (= NULL 은 불가!) |
2) BETWEEN A AND B — 경계값을 포함한다 
-- ============================================================
-- 【이해용 예제】 급여가 1000 이상 2000 이하인 사원
-- ============================================================
SELECT ENAME, SAL
FROM EMP
WHERE SAL BETWEEN 1000 AND 2000; -- 1000과 2000도 '포함' 된다
-- ENAME SAL
-- ------ ----
-- ALLEN 1600
-- WARD 1250
-- MARTIN 1250
-- TURNER 1500
-- ADAMS 1100
-- MILLER 1300 → 6건
-- 위와 완전히 똑같은 결과
SELECT ENAME, SAL
FROM EMP
WHERE SAL >= 1000 -- 이상
AND SAL <= 2000; -- 이하
-- → 동일한 6건
SQL
복사
-- ============================================================
-- 【시험용 예제】 BETWEEN 의 세 가지 함정 ★★
-- ============================================================
-- ⚠️ 함정 ① 순서를 바꾸면 결과가 0건이 된다
SELECT ENAME FROM EMP WHERE SAL BETWEEN 2000 AND 1000;
-- → 0건! BETWEEN 은 '작은 값 AND 큰 값' 순서로 써야 한다
-- (내부적으로 SAL >= 2000 AND SAL <= 1000 이 되어 만족하는 행이 없음)
-- ⚠️ 함정 ② NOT BETWEEN 은 경계값을 '제외' 한다
SELECT ENAME, SAL FROM EMP WHERE SAL NOT BETWEEN 1000 AND 2000;
-- → SAL < 1000 OR SAL > 2000 인 사원 (1000과 2000은 포함되지 않음)
-- ENAME SAL
-- ------ -----
-- SMITH 800
-- JONES 2975
-- ... → 8건 (14 - 6)
-- ⚠️ 함정 ③ 날짜에도 쓸 수 있지만 '시분초'에 주의
-- HIREDATE BETWEEN '81/01/01' AND '81/12/31' 로 쓰면
-- 12월 31일 00시 00분 00초까지만 포함되어, 그날 오후 데이터가 누락될 수 있다
SQL
복사
3) IN — 여러 값 중 하나
-- ============================================================
-- 【이해용 예제】 직무가 CLERK 또는 MANAGER 인 사원
-- ============================================================
SELECT ENAME, JOB
FROM EMP
WHERE JOB IN ('CLERK', 'MANAGER'); -- 목록 안의 값 중 하나면 통과
-- ENAME JOB
-- ------ -------
-- SMITH CLERK
-- JONES MANAGER
-- BLAKE MANAGER
-- CLARK MANAGER
-- ADAMS CLERK
-- JAMES CLERK
-- MILLER CLERK → 7건
-- 위와 완전히 똑같은 결과 (OR 로 풀어 쓴 것)
SELECT ENAME, JOB
FROM EMP
WHERE JOB = 'CLERK'
OR JOB = 'MANAGER';
-- → 동일한 7건
-- ⭐ 조건이 많아질수록 IN 이 훨씬 짧고 읽기 좋다
SQL
복사
4) IS NULL — NULL 전용 비교 (06강 회수)
-- ============================================================
-- 【시험용 예제】 NULL은 = 로 비교할 수 없다 ★★
-- ============================================================
-- ❌ 오류는 안 나지만 0건이 나온다
SELECT ENAME, COMM FROM EMP WHERE COMM = NULL;
-- → 0건 (COMM = NULL 의 결과가 UNKNOWN 이라 아무 행도 통과 못 함)
-- ✅ IS NULL 을 써야 한다
SELECT ENAME, COMM FROM EMP WHERE COMM IS NULL;
-- ENAME COMM
-- ------ ------
-- SMITH (NULL)
-- JONES (NULL)
-- ... → 10건
-- ✅ NULL이 아닌 행을 찾을 때는 IS NOT NULL
SELECT ENAME, COMM FROM EMP WHERE COMM IS NOT NULL;
-- ENAME COMM
-- ------ -----
-- ALLEN 300
-- WARD 500
-- MARTIN 1400
-- TURNER 0 ← 0 은 NULL이 아니다! (06강) ⭐
-- → 4건
SQL
복사
TURNER의 커미션 0은 NULL이 아닙니다."값이 0인 것" 과 "값이 없는 것" 은 완전히 다릅니다. (06강 회수)4. LIKE 와 와일드카드 

1) 두 가지 와일드카드
기호 | 의미 | 예 | 매칭되는 것 |
% | 0자 이상의 임의 문자 | 'S%' | S, SM, SMITH, SCOTT … |
_ | 정확히 1자의 임의 문자 | 'S_' | SM, SA … (2글자만) |
-- ============================================================
-- 【이해용 예제】 LIKE 기본 패턴 3가지
-- ============================================================
-- (1) S 로 시작하는 이름
SELECT ENAME FROM EMP WHERE ENAME LIKE 'S%';
-- ENAME
-- -----
-- SMITH
-- SCOTT → 2건
-- (2) S 로 끝나는 이름
SELECT ENAME FROM EMP WHERE ENAME LIKE '%S';
-- ENAME
-- -----
-- JAMES
-- ADAMS → 2건
-- (3) 이름 안에 AR 이 들어가는 사람
SELECT ENAME FROM EMP WHERE ENAME LIKE '%AR%';
-- ENAME
-- ------
-- WARD
-- MARTIN
-- CLARK → 3건
SQL
복사
-- ============================================================
-- 【시험용 예제】 _ 와 % 의 차이를 정확히 구분하기 ★★
-- ============================================================
-- '_A%' : 첫 글자는 아무거나 1자, 둘째 글자가 A, 그 뒤는 자유
SELECT ENAME FROM EMP WHERE ENAME LIKE '_A%';
-- ENAME
-- ------
-- WARD ← W-A-R-D : 둘째가 A ✅
-- MARTIN ← M-A-R... : 둘째가 A ✅
-- JAMES ← J-A-M... : 둘째가 A ✅
-- → 3건
-- ⚠️ ALLEN 은 A가 '첫째' 글자이므로 매칭되지 않는다!
-- 'A%' 와 비교해 보면 차이가 분명해진다
SELECT ENAME FROM EMP WHERE ENAME LIKE 'A%';
-- ENAME
-- ------
-- ALLEN ← 첫 글자가 A ✅
-- ADAMS ← 첫 글자가 A ✅
-- → 2건
-- '__A%' : 셋째 글자가 A
SELECT ENAME FROM EMP WHERE ENAME LIKE '__A%';
-- ENAME
-- ------
-- BLAKE ← B-L-A-K-E : 셋째가 A ✅
-- CLARK ← C-L-A-R-K : 셋째가 A ✅
-- → 2건
--
-- ⭐ 밑줄(_) 하나가 정확히 한 글자다. 개수를 세는 문제가 자주 출제된다.
SQL
복사
2) ESCAPE — % 나 _ 자체를 찾고 싶을 때 
문제: "할인율 50% 라는 문자열이 들어간 상품"을 찾으려면?
LIKE '%50%%' 라고 쓰면 마지막 %도 와일드카드로 해석되어 원하는 결과가 안 나옵니다.
-- ============================================================
-- 【시험용 예제】 ESCAPE 절로 와일드카드를 '평범한 문자'로 만들기 ★
-- ============================================================
-- 예시 데이터 [PRODUCT]
-- 상품코드 상품명
-- -------- ----------------
-- P01 50% 할인상품
-- P02 특가 50000원
-- P03 100% 국산
-- ❌ 그냥 쓰면 % 가 와일드카드로 해석된다
SELECT * FROM PRODUCT WHERE PROD_NM LIKE '%50%%';
-- → P01, P02 둘 다 나옴 (50 이 들어간 모든 것) ⚠️
-- ✅ ESCAPE 로 '탈출 문자'를 지정한다
SELECT * FROM PRODUCT
WHERE PROD_NM LIKE '%50\%%' ESCAPE '\';
-- ↑ ↑
-- │ └ 이 % 는 '진짜 퍼센트 문자' (앞에 \ 가 붙었으므로)
-- └── ESCAPE 로 지정한 탈출 문자
-- 상품코드 상품명
-- -------- ------------
-- P01 50% 할인상품 → 1건 ✅
-- ⭐ ESCAPE 문자는 아무 글자나 지정할 수 있다
-- ESCAPE '#' 로 지정했다면 '%50#%%' 처럼 쓴다
-- ⭐ 밑줄(_)도 똑같이 탈출시킬 수 있다 : LIKE 'A\_B' ESCAPE '\'
SQL
복사
5. 논리 연산자와 우선순위 


1) 세 가지 논리 연산자
연산자 | 의미 | 통과 조건 |
AND | 그리고 | 모든 조건이 TRUE |
OR | 또는 | 하나라도 TRUE |
NOT | 부정 | 조건을 뒤집음 |
2)
AND 가 OR 보다 우선순위가 높다 


곱셈이 덧셈보다 먼저인 것과 같습니다.2 + 3 * 4 가 2 + 12 이듯이, A OR B AND C 는 A OR (B AND C) 입니다.
-- ============================================================
-- 【시험용 예제】 괄호 하나로 결과가 완전히 달라진다 ★★★
-- 질문: "30번 부서이면서 급여 1500 이상이거나, 직무가 CLERK 인 사원"
-- ============================================================
-- (A) 괄호 없음 → AND 가 먼저 묶인다
SELECT ENAME, JOB, DEPTNO, SAL
FROM EMP
WHERE DEPTNO = 30 AND SAL >= 1500 OR JOB = 'CLERK';
-- 해석: (DEPTNO = 30 AND SAL >= 1500) OR JOB = 'CLERK'
-- └────── 30번 부서의 고액자 ──────┘ └ 부서 무관 모든 CLERK ┘
-- ENAME JOB DEPTNO SAL
-- ------ -------- ------ -----
-- ALLEN SALESMAN 30 1600 ← 30번 & 1500이상
-- BLAKE MANAGER 30 2850 ← 30번 & 1500이상
-- TURNER SALESMAN 30 1500 ← 30번 & 1500이상
-- SMITH CLERK 20 800 ← CLERK (20번 부서인데도 나옴!) ⚠️
-- ADAMS CLERK 20 1100 ← CLERK
-- JAMES CLERK 30 950 ← CLERK
-- MILLER CLERK 10 1300 ← CLERK (10번 부서!) → 7건
-- (B) 괄호 있음 → OR 를 먼저 묶는다
SELECT ENAME, JOB, DEPTNO, SAL
FROM EMP
WHERE DEPTNO = 30 AND (SAL >= 1500 OR JOB = 'CLERK');
-- 해석: 30번 부서인 사람 중에서, 급여 1500 이상이거나 CLERK 인 사람
-- ENAME JOB DEPTNO SAL
-- ------ -------- ------ -----
-- ALLEN SALESMAN 30 1600
-- BLAKE MANAGER 30 2850
-- TURNER SALESMAN 30 1500
-- JAMES CLERK 30 950 ← 30번 부서의 CLERK 만 → 4건
-- ⭐ 같은 조건인데 7건 vs 4건! 괄호 하나 차이다.
-- ⭐ 실무 원칙: AND 와 OR 를 섞어 쓸 때는 '반드시 괄호를 명시' 한다.
SQL
복사
3) 연산자 우선순위 종합 
순위 | 연산자 |
1 | 괄호 ( ) |
2 | 산술 연산자 * / + - |
3 | 연결 연산자 || |
4 | 비교 연산자 = <> > < >= <= |
5 | SQL 연산자 IS NULL LIKE IN BETWEEN |
6 | NOT |
7 | AND |
8 | OR |
암기 문장: "산술 → 연결 → 비교 → SQL → NOT → AND → OR"
뒤로 갈수록 나중에 계산됩니다. 가장 나중이 OR 라는 것만 확실히 기억하세요.6. 부정 연산자
긍정 | 부정 | 의미 |
= | <> != ^= | 같지 않다 |
BETWEEN A AND B | NOT BETWEEN A AND B | 범위 밖 (경계값 제외) |
IN (…) | NOT IN (…) | 목록에 없음 ![]() |
LIKE '패턴' | NOT LIKE '패턴' | 패턴과 다름 |
IS NULL | IS NOT NULL | NULL이 아님 |
-- ============================================================
-- 【이해용 예제】 조건 뒤집기
-- ============================================================
SELECT ENAME, JOB
FROM EMP
WHERE JOB NOT IN ('CLERK', 'MANAGER'); -- CLERK도 MANAGER도 아닌 사원
-- ENAME JOB
-- ------ ---------
-- ALLEN SALESMAN
-- WARD SALESMAN
-- MARTIN SALESMAN
-- SCOTT ANALYST
-- KING PRESIDENT
-- TURNER SALESMAN
-- FORD ANALYST → 7건 (14 - 7)
SQL
복사
7. NULL과 WHERE — NOT IN 의 함정 


06강에서 미뤄둔 숙제입니다. 원리를 모르면 절대 못 푸는 대표 문제입니다.1) 현상 — 결과가 무조건 0건이 된다
-- ============================================================
-- 【시험용 예제】 NOT IN 목록에 NULL이 하나라도 있으면? ★★★
-- ============================================================
-- IN 은 정상 동작한다
SELECT ENAME, DEPTNO FROM EMP WHERE DEPTNO IN (10, 20, NULL);
-- ENAME DEPTNO
-- ------ ------
-- CLARK 10
-- SMITH 20
-- ... → 8건 ✅ (10번 3명 + 20번 5명)
-- ❌ NOT IN 은 0건이 된다!
SELECT ENAME, DEPTNO FROM EMP WHERE DEPTNO NOT IN (10, 20, NULL);
-- → 0건 ⚠️ 30번 부서 사원이 6명이나 있는데도!
SQL
복사
2) 왜 그런가 — 단계별로 풀어보기 
30번 부서 사원(예: JAMES)을 대입해서 확인해 봅시다
단계 | 식 | 결과 |
① | 30 <> 10 | TRUE |
② | 30 <> 20 | TRUE |
③ | 30 <> NULL | UNKNOWN ![]() |
종합 | TRUE AND TRUE AND UNKNOWN | UNKNOWN |
판정 | WHERE절 통과? | 탈락 |
AND 진리표에서 UNKNOWN이 섞이면TRUE AND UNKNOWN = UNKNOWN (참인지 확신할 수 없으므로)
반면 FALSE AND UNKNOWN = FALSE (이미 거짓이 확정)3) IN 은 왜 괜찮은가?
연산 | 전개 | NULL의 영향 |
IN (10, 20, NULL) | =10 **OR** =20 OR =NULL | TRUE OR UNKNOWN = TRUE ![]() |
NOT IN (10, 20, NULL) | <>10 **AND** <>20 AND <>NULL | TRUE AND UNKNOWN = UNKNOWN ![]() |
차이는 OR 냐 AND 냐입니다.IN은 OR로 풀려서 하나만 TRUE면 통과하지만,
NOT IN은 AND로 풀려서 UNKNOWN 하나가 전체를 오염시킵니다.4) 해결 방법
-- ✅ 방법 ① NULL을 목록에서 제거한다
SELECT ENAME, DEPTNO FROM EMP WHERE DEPTNO NOT IN (10, 20);
-- → 30번 부서 6건 정상 조회 ✅
-- ✅ 방법 ② 서브쿼리를 쓸 때는 NULL을 걸러낸다 (15강에서 자세히)
SELECT ENAME FROM EMP
WHERE EMPNO NOT IN ( SELECT MGR FROM EMP WHERE MGR IS NOT NULL );
-- └─ 이 조건이 없으면 0건! ⚠️
-- (KING 의 MGR 이 NULL 이므로, 안 걸러내면 목록에 NULL이 들어간다)
SQL
복사
실무에서 가장 자주 터지는 버그입니다.NOT IN (서브쿼리) 를 쓸 때는 서브쿼리 결과에 NULL이 없는지 반드시 확인하세요.
이 문제는 15강 서브쿼리에서 다시 만납니다.8. 출제 포인트 한눈에 정리
# | 꼭 외울 것 | 핵심 |
1 | WHERE절의 통과 기준 | TRUE인 행만 (FALSE·UNKNOWN 모두 탈락) |
2 | 같지 않다 | <> != ^= 셋 다 동일 |
3 | 문자 비교 | 대소문자 구분, 사전 순으로 비교 |
4 | 날짜 비교 | 문자열 비교는 위험 → TO_DATE 명시적 변환 |
5 | BETWEEN A AND B | 경계값 포함, >= A AND <= B 와 동일 |
6 | BETWEEN 순서 | 작은 값 먼저, 뒤바꾸면 0건 |
7 | NOT BETWEEN | 경계값 제외 |
8 | IN (…) | OR 로 풀림 |
9 | % vs _ | % = 0자 이상, _ = 정확히 1자 ![]() |
10 | ESCAPE | % _ 자체를 검색할 때 사용 |
11 | NULL 비교 | = NULL → IS NULL ![]() |
12 | 논리 연산자 우선순위 | NOT > AND > OR ![]() |
13 | 전체 우선순위 | 괄호 → 산술 → 연결 → 비교 → SQL → NOT → AND → OR |
14 | NOT IN + NULL | 무조건 0건 (AND로 풀려 UNKNOWN 전파) ![]() ![]() |
9. 확인 문제
Q1. WHERE SAL BETWEEN 1000 AND 2000 과 같은 의미의 조건은?
① SAL > 1000 AND SAL < 2000
② SAL >= 1000 AND SAL <= 2000
③ SAL >= 1000 OR SAL <= 2000
④ SAL IN (1000, 2000)
정답 보기
Q2. WHERE SAL BETWEEN 2000 AND 1000 의 결과는?
정답 보기
Q3. EMP 테이블에서 WHERE ENAME LIKE '_A%' 의 결과로 옳은 것은?
① ALLEN, ADAMS
② WARD, MARTIN, JAMES
③ ALLEN, ADAMS, WARD, MARTIN, JAMES
④ CLARK, BLAKE
정답 보기
Q4. 아래 두 SQL의 결과 건수가 다른 이유는?
SQL | 결과 |
(A) WHERE DEPTNO = 30 AND SAL >= 1500 OR JOB = 'CLERK' | 7건 |
(B) WHERE DEPTNO = 30 AND (SAL >= 1500 OR JOB = 'CLERK') | 4건 |
정답 보기
Q5. 논리 연산자의 우선순위를 높은 것부터 나열하시오.
정답 보기









