🎯 SQLD 벼락치기 튜터 — 진단 시작
내일 시험까지 시간이 촉박하니 바로 진단으로 들어갑니다. 10문제 모두 풀고 나서 한 번에 답 알려주세요 (예: 1-③ 2-① 3-④ ...) 정답 공개 후 취약 영역 + 오늘 학습 로드맵 바로 제시할게요.
📋 진단 문제 (10문항)
[1과목] 데이터 모델링의 이해
Q1. 정규화 — 중
아래 테이블에서 발생하는 이상 현상과 이를 해결하기 위한 정규화 단계로 올바른 것은?
주문(주문번호, 고객번호, 고객명, 상품번호, 상품명, 수량)
- 기본키: (주문번호, 상품번호)
- 고객명은 고객번호에만 종속
- 상품명은 상품번호에만 종속
① 부분 함수 종속 → 1NF로 해결
② 이행 함수 종속 → 2NF로 해결
③ 부분 함수 종속 → 2NF로 해결
④ 이행 함수 종속 → 3NF로 해결
Q2. 엔터티/관계 — 중
ERD의 관계에 대한 설명으로 옳지 않은 것은?
① 관계는 엔터티 간의 업무적 연관성을 표현한다
② 관계차수(Cardinality)는 1:1, 1:M, M:N으로 구분된다
③ M:N 관계는 물리 모델에서 그대로 구현 가능하다
④ 관계에는 선택성(Optionality)이 존재한다
Q3. 식별자 — 상
주식별자(Primary Identifier)의 특징으로 모두 올바른 것은?
ㄱ. 유일성 — 모든 인스턴스를 유일하게 구분해야 한다
ㄴ. 최소성 — 주식별자를 구성하는 속성의 수는 최소화해야 한다
ㄷ. 불변성 — 식별자의 값은 자주 변경되어서는 안 된다
ㄹ. 존재성 — NULL 값을 가질 수 없다
① ㄱ, ㄴ
② ㄱ, ㄴ, ㄷ
③ ㄱ, ㄷ, ㄹ
④ ㄱ, ㄴ, ㄷ, ㄹ
[2과목] SQL 기본 및 활용
Q4. NULL 처리 — 중
아래 SQL의 실행 결과로 올바른 것은?
sql
SELECT 100 + NULL,
NVL(NULL, 0) + 100,
NULLIF(100, 100)
FROM DUAL;
① NULL, 100, NULL
② NULL, 100, 0
③ 100, 100, NULL
④ 0, 100, 0
Q5. OUTER JOIN — 중
다음 두 테이블과 SQL을 보고 결과 행 수로 올바른 것은?
[A 테이블] [B 테이블]
ID ID
-- --
1 1
2 3
3
sql
SELECT A.ID, B.ID
FROM A LEFT OUTER JOIN B ON A.ID = B.ID;
① 2행
② 3행
③ 4행
④ 5행
Q6. GROUP BY / HAVING — 중
아래 SQL에서 문법 오류가 있는 것은?
sql
-- ①
SELECT DEPTNO, AVG(SAL)
FROM EMP
GROUP BY DEPTNO
HAVING AVG(SAL) > 2000;
-- ②
SELECT DEPTNO, AVG(SAL)
FROM EMP
WHERE AVG(SAL) > 2000
GROUP BY DEPTNO;
-- ③
SELECT DEPTNO, MAX(SAL)
FROM EMP
GROUP BY DEPTNO
ORDER BY MAX(SAL) DESC;
-- ④
SELECT DEPTNO, COUNT(*)
FROM EMP
GROUP BY DEPTNO
HAVING COUNT(*) >= 3;
① ①번
② ②번
③ ③번
④ ④번
Q7. 서브쿼리 — 상
아래 SQL의 결과로 올바른 것은?
sql
-- EMP 테이블: ENAME, DEPTNO, SAL
-- 부서별 평균 SAL보다 자신의 SAL이 높은 직원 조회
SELECT ENAME, SAL
FROM EMP E1
WHERE SAL > (SELECT AVG(SAL)
FROM EMP E2
WHERE E2.DEPTNO = E1.DEPTNO);
① 전체 평균 SAL보다 높은 직원 조회
② 자신이 속한 부서의 평균보다 SAL이 높은 직원 조회
③ 모든 부서 중 SAL이 가장 높은 직원 조회
④ 문법 오류 — 상관 서브쿼리는 사용 불가
Q8. 윈도우 함수 — 상
아래 SQL에서 RANK()와 ROW_NUMBER()의 차이로 올바른 것은?
sql
SELECT ENAME, SAL,
RANK() OVER (ORDER BY SAL DESC) AS RNK,
ROW_NUMBER() OVER (ORDER BY SAL DESC) AS RN
FROM EMP;
-- SAL: 5000, 3000, 3000, 2000 순서로 존재
| SAL | RNK | RN |
|---|---|---|
| 5000 | ? | ? |
| 3000 | ? | ? |
| 3000 | ? | ? |
| 2000 | ? | ? |
① RNK: 1,2,2,3 / RN: 1,2,2,4
② RNK: 1,2,2,4 / RN: 1,2,3,4
③ RNK: 1,2,3,4 / RN: 1,2,2,4
④ RNK: 1,2,2,4 / RN: 1,2,2,4
Q9. CASE/DECODE — 중
아래 두 SQL이 동일한 결과를 내는지 판단하시오.
sql
-- SQL A
SELECT DECODE(GRADE, 'A', '우수', 'B', '보통', '미흡') AS 평가
FROM STUDENT;
-- SQL B
SELECT CASE GRADE
WHEN 'A' THEN '우수'
WHEN 'B' THEN '보통'
ELSE '미흡'
END AS 평가
FROM STUDENT;
① 동일한 결과 — DECODE와 CASE WHEN은 항상 동일
② 다른 결과 — DECODE는 Oracle 전용, CASE는 표준 SQL
③ 동일한 결과 — 위 예시 기준으로는 동일하게 동작
④ 다른 결과 — NULL 처리 방식이 달라 결과가 다름
Q10. DCL/DDL/DML/TCL 구분 — 중
아래 SQL 명령어를 DDL / DML / TCL로 올바르게 분류한 것은?
TRUNCATE TABLE EMP;
DELETE FROM EMP;
ROLLBACK;
ALTER TABLE EMP ADD COLUMN AGE NUMBER;
| 구분 | TRUNCATE | DELETE | ROLLBACK | ALTER |
|---|---|---|---|---|
| ① | DDL | DML | TCL | DDL |
| ② | DML | DML | TCL | DDL |
| ③ | DDL | DML | DML | DDL |
| ④ | DDL | DDL | TCL | DML |
✏️ 답안 제출 방법
1-① 2-③ 3-④ ... 형식으로 한 번에 적어주세요
모든 답을 받으면 바로 채점 + 취약 분석 + 오늘 저녁 학습 플랜 드릴게요! 💪
You said: 1-4
1-4 2-3 3-4 4-1 5-2 6-2 7-4 8-2 9-1 10-1
3:56 PM
Claude responded: 📊 진단 결과 — 채점 완료
Graded database exam, identified three weak areas, prescribed targeted study plan
Graded database exam, identified three weak areas, prescribed targeted study plan
📊 진단 결과 — 채점 완료
점수: 7 / 10 (70점 환산)
| 문항 | 영역 | 정답 | 제출 | 결과 |
|---|---|---|---|---|
| Q1 | 정규화 (2NF/3NF) | ③ | ④ | ❌ |
| Q2 | ERD/관계 | ③ | ③ | ✅ |
| Q3 | 주식별자 | ④ | ④ | ✅ |
| Q4 | NULL 처리 | ① | ① | ✅ |
| Q5 | OUTER JOIN | ② | ② | ✅ |
| Q6 | GROUP BY/HAVING | ② | ② | ✅ |
| Q7 | 상관 서브쿼리 | ② | ④ | ❌ |
| Q8 | 윈도우 함수 | ② | ② | ✅ |
| Q9 | DECODE vs CASE | ③ | ① | ❌ |
| Q10 | DDL/DML/TCL | ① | ① | ✅ |
❌ 오답 3개 — 핵심 해설
Q1. 정규화 — 부분 함수 종속 → 2NF
선택한 ④번은 “이행 함수 종속 → 3NF” → 다른 개념입니다
기본키: (주문번호, 상품번호) ← 복합키
고객명 → 고객번호에만 종속 ← 복합키의 일부에만 종속
상품명 → 상품번호에만 종속 ← 복합키의 일부에만 종속
✅ 복합키의 일부에만 종속 = 부분 함수 종속 → 2NF로 해결
✅ 이행 함수 종속(A→B→C): 3NF로 해결 (예: 고객번호→고객명→고객등급)
Q7. 상관 서브쿼리 — 사용 가능하며, 부서별 평균 비교
선택한 ④번 “문법 오류 — 상관 서브쿼리 불가” → 완전히 반대입니다
sql
WHERE SAL > (SELECT AVG(SAL)
FROM EMP E2
WHERE E2.DEPTNO = E1.DEPTNO) -- ← 외부 쿼리 참조
- 상관 서브쿼리: 서브쿼리 안에서 외부 테이블(
E1)을 참조하는 구조 - 행마다 서브쿼리가 실행됨 → 자신의 부서 평균과 비교
- 매우 자주 출제되는 패턴! ⚠️
Q9. DECODE vs CASE WHEN — 항상 동일하지 않음
선택한 ①번 “항상 동일” → NULL 처리 시 달라집니다
sql
-- GRADE = NULL 인 행이 있을 때:
DECODE(GRADE, NULL, '없음', '기타') -- ✅ NULL = NULL → '없음' 출력
CASE GRADE WHEN NULL THEN '없음' -- ❌ NULL = NULL → FALSE → ELSE로 빠짐
ELSE '기타' END
| 비교 | DECODE | CASE WHEN |
|---|---|---|
| NULL 비교 | NULL = NULL → 같다 | NULL = NULL → 다르다 |
| 표준 여부 | Oracle 전용 | ANSI 표준 |
위 예시에서는 NULL 케이스가 없으니 결과 동일 → 정답 ③
🔍 취약 영역 진단
| 영역 | 상태 | 비고 |
|---|---|---|
| 정규화 (1NF~BCNF) | 🔴 취약 | 부분/이행 종속 혼동 |
| 상관 서브쿼리 | 🔴 취약 | 개념 자체를 오해 |
| DECODE/CASE NULL | 🟡 보통 | 세부 차이 미숙 |
| JOIN / HAVING / 윈도우함수 | 🟢 양호 | 기본기 OK |
| DDL/DML/TCL 구분 | 🟢 양호 |
🗓️ 오늘 저녁 학습 로드맵
남은 시간 약 5~6시간 기준 (저녁 ~ 자정)
⏰ 1시간 — 🔴 정규화 집중 (1NF→2NF→3NF→BCNF 구분 + 기출 패턴)
⏰ 1시간 — 🔴 서브쿼리 집중 (단일행/다중행/상관/인라인뷰)
⏰ 1시간 — ★★★ JOIN 유형 총정리 (INNER/OUTER/SELF/CROSS)
⏰ 1시간 — ★★★ 윈도우함수 + DECODE/CASE 마무리
⏰ 30분 — ★★☆ 트랜잭션/TCL + DDL 특징 (TRUNCATE vs DELETE)
⏰ 30분 — 🎯 최종정리 모드 (암기카드)
🚀 다음 단계
어떤 모드로 시작할까요?
👉 [개념모드] 정규화 — 1NF~BCNF 핵심 표로 정리
👉 [문제모드] 서브쿼리 — 기출 유형 5문제 집중 훈련
👉 [약점공략] 정규화 — 정규화만 문제 집중 공략
You said: 각 모드 하나씩 완료해나가자.
각 모드 하나씩 완료해나가자.
4:01 PM
Claude responded: 📚 [개념모드] 정규화 — 1NF → BCNF 핵심 정리
순차적 학습 모드를 진행하기로 결정했다
순차적 학습 모드를 진행하기로 결정했다
📚 [개념모드] 정규화 — 1NF → BCNF 핵심 정리
🔑 핵심 개념: 함수 종속성 먼저 잡기
함수 종속 (A → B): A 값이 결정되면 B 값도 결정됨
= "A가 B를 결정한다"
예) 학번 → 학생명 ✅
(학번, 과목) → 성적 ✅ (복합키)
학번 → 성적 ❌ (과목도 알아야 성적이 결정됨)
📊 정규화 단계 — 한눈에 비교
| 단계 | 제거 대상 | 핵심 키워드 | 기억법 |
|---|---|---|---|
| 1NF | 반복 그룹 / 다중값 속성 | 원자값 | “칸 하나 = 값 하나” |
| 2NF | 부분 함수 종속 | 복합키 일부에만 종속 | “복합키면 2NF 의심” |
| 3NF | 이행 함수 종속 | A→B→C 구조 | “돌아가서 종속” |
| BCNF | 결정자가 후보키가 아닌 경우 | 모든 결정자 = 후보키 | “3NF보다 엄격한 버전” |
🔴 2NF — 부분 함수 종속 제거
조건: 기본키가 복합키일 때만 발생
[위반 예시]
수강(학번, 과목코드, 성적, 학생명)
기본키: (학번, 과목코드)
학번, 과목코드 → 성적 ✅ 완전 함수 종속
학번 → 학생명 ❌ 부분 함수 종속 (복합키 일부에만 종속)
[해결] 테이블 분리
수강(학번, 과목코드, 성적) ← 복합키 유지
학생(학번, 학생명) ← 부분 종속 분리
🔴 3NF — 이행 함수 종속 제거
조건: 기본키가 단일키일 때도 발생 가능
[위반 예시]
직원(직원번호, 부서코드, 부서명)
기본키: 직원번호
직원번호 → 부서코드 ✅
부서코드 → 부서명 ✅
직원번호 → 부서명 ❌ 이행 함수 종속 (직원번호 → 부서코드 → 부서명)
[해결] 테이블 분리
직원(직원번호, 부서코드)
부서(부서코드, 부서명)
🔴 BCNF — 결정자가 후보키가 아닌 경우
3NF를 만족해도 BCNF 위반 가능 (시험 출제 포인트!)
[위반 예시]
수강(학생, 과목, 교수)
기본키: (학생, 과목)
규칙: 한 과목은 여러 교수가 담당, 한 교수는 하나의 과목만 담당
교수 → 과목 (교수가 결정자인데 교수는 후보키가 아님) ❌ BCNF 위반
[해결]
교수배정(교수, 과목)
수강(학생, 교수)
⚡ 시험 출제 핵심 패턴 3가지
① 복합키 + 일부에만 종속 보이면 → 2NF 위반 (부분 함수 종속)
② A→B→C 구조 보이면 → 3NF 위반 (이행 함수 종속)
③ "정규화의 단점"을 물으면 → 테이블 수 증가, 조인 증가 → 성능 저하
🧨 자주 나오는 함정
| 함정 | 정답 |
|---|---|
| 기본키가 단일키인데 2NF 위반? | ❌ 불가능 (2NF는 복합키 전제) |
| 2NF 만족하면 3NF도 만족? | ❌ 아님, 이행 종속 별도 확인 |
| TRUNCATE는 정규화와 관련? | ❌ 무관 (DDL 개념) |
| 역정규화(반정규화)는 나쁜 것? | ❌ 성능 위해 의도적으로 수행 |
✅ 개념모드 완료
다음 순서: [문제모드] 서브쿼리
정규화 개념 이해됐으면 “다음” 헷갈리는 부분 있으면 질문 먼저 해주세요! 💪
You said: 다음
다음
4:23 PM
Claude responded: 🧩 [문제모드] 서브쿼리 — 기출 유형 5문제
다음
다음
🧩 [문제모드] 서브쿼리 — 기출 유형 5문제
답 고르면 바로 해설 드립니다. 5문제 모두 풀고 한 번에 제출해주세요!
Q1. 서브쿼리 위치 구분 — 중
서브쿼리 위치에 따른 명칭이 올바르게 연결된 것은?
sql
SELECT (SELECT MAX(SAL) FROM EMP) -- ⓐ
FROM (SELECT * FROM EMP WHERE DEPTNO=10) -- ⓑ
WHERE SAL > (SELECT AVG(SAL) FROM EMP) -- ⓒ
① ⓐ 스칼라, ⓑ 인라인뷰, ⓒ 중첩서브쿼리
② ⓐ 인라인뷰, ⓑ 스칼라, ⓒ 중첩서브쿼리
③ ⓐ 중첩서브쿼리, ⓑ 인라인뷰, ⓒ 스칼라
④ ⓐ 스칼라, ⓑ 중첩서브쿼리, ⓒ 인라인뷰
Q2. 단일행 vs 다중행 서브쿼리 — 중
아래 SQL 중 오류가 발생하는 것은?
sql
-- ①
SELECT * FROM EMP
WHERE SAL = (SELECT SAL FROM EMP WHERE ENAME = 'KING');
-- ②
SELECT * FROM EMP
WHERE SAL = (SELECT SAL FROM EMP WHERE DEPTNO = 10);
-- ③
SELECT * FROM EMP
WHERE SAL IN (SELECT SAL FROM EMP WHERE DEPTNO = 10);
-- ④
SELECT * FROM EMP
WHERE SAL > ANY (SELECT SAL FROM EMP WHERE DEPTNO = 10);
① ①번
② ②번
③ ③번
④ ④번
Q3. 다중행 연산자 — 중
아래 설명에서 ALL 과 ANY 에 대한 설명으로 옳지 않은 것은?
① > ALL (서브쿼리) : 서브쿼리 결과의 최댓값보다 크다
② > ANY (서브쿼리) : 서브쿼리 결과의 최솟값보다 크다
③ = ANY (서브쿼리) : IN과 동일한 결과
④ < ALL (서브쿼리) : 서브쿼리 결과의 최솟값보다 작다
Q4. 상관 서브쿼리 — 상
아래 SQL의 실행 결과로 올바른 것은?
sql
-- EMP 테이블
-- EMPNO ENAME DEPTNO SAL
-- 101 ALICE 10 5000
-- 102 BOB 10 3000
-- 103 CAROL 20 4000
-- 104 DAVE 20 4500
SELECT ENAME
FROM EMP E1
WHERE EXISTS (
SELECT 1
FROM EMP E2
WHERE E2.DEPTNO = E1.DEPTNO
AND E2.SAL > E1.SAL
);
① ALICE, CAROL 출력
② BOB, CAROL 출력
③ BOB, CAROL, DAVE 출력 (잘못된 이해)
④ ALICE, BOB, CAROL, DAVE 전원 출력
Q5. 인라인뷰 + 순위 — 상
각 부서에서 SAL이 가장 높은 직원 1명씩 조회하려 한다. 올바른 SQL은?
sql
-- ①
SELECT ENAME, DEPTNO, SAL
FROM EMP
WHERE SAL = MAX(SAL)
GROUP BY DEPTNO;
-- ②
SELECT ENAME, DEPTNO, SAL
FROM (
SELECT ENAME, DEPTNO, SAL,
RANK() OVER (PARTITION BY DEPTNO ORDER BY SAL DESC) AS RNK
FROM EMP
)
WHERE RNK = 1;
-- ③
SELECT ENAME, DEPTNO, MAX(SAL)
FROM EMP
GROUP BY DEPTNO;
-- ④
SELECT ENAME, DEPTNO, SAL
FROM EMP
WHERE SAL IN (SELECT MAX(SAL) FROM EMP);
① ①번
② ②번
③ ③번
④ ④번
✏️ 답안 제출
1-① 2-② ... 형식으로 제출해주세요!
You said: 1-1
1-1 2-2 3-3 (풀긴 풀었는데 설명 필요) 4-4 (이유: 서브쿼리에서 부서번호가 같은 것 중 sal이 큰 것을 반환하면 각 부서의 sal이 큰 alice, dave가 추출됨. 이것들이 존재하니, e1에 있는 데이터가 모두 출력됨 / EXISTS는 존재하면 true, 존재하지 않으면 false 반환) 5-2
4:32 PM
Claude responded: 📊 [문제모드] 서브쿼리 — 채점 결과
문제 채점 및 오류 분석 진행
문제 채점 및 오류 분석 진행
📊 [문제모드] 서브쿼리 — 채점 결과
| 문항 | 정답 | 제출 | 결과 |
|---|---|---|---|
| Q1 | ① | ① | ✅ |
| Q2 | ② | ② | ✅ |
| Q3 | ⚠️ | ③ | 문제 오류 (아래 설명) |
| Q4 | ② | ④ | ❌ |
| Q5 | ② | ② | ✅ |
⚠️ Q3 — 문제 오류 + 개념 정리
솔직히 말씀드리면 제가 낸 문제가 잘못됐습니다. 4개 보기가 모두 옳은 설명이라 “옳지 않은 것”이 없어요. 대신 핵심 개념으로 정리합니다.
> ALL (값들) → 모든 값보다 크다 = MAX보다 크다
> ANY (값들) → 하나라도 크면 됨 = MIN보다 크다
= ANY (값들) → 하나라도 같으면 됨 = IN 과 동일 ✅
< ALL (값들) → 모든 값보다 작다 = MIN보다 작다
🔥 시험에 자주 나오는 함정
= ANY → IN 과 동일 ✅ (맞음)
<> ANY → NOT IN 과 동일? ❌ (틀림! 함정!)
<> ALL → NOT IN 과 동일 ✅ (이게 맞음)
암기:
NOT IN의 짝은<> ALL,<> ANY가 아님!
❌ Q4 — EXISTS 완전 정복
정답: ② BOB, CAROL
사용자 풀이의 핵심 오류:
EXISTS는 전체 결과가 아닌, 현재 행(E1) 기준으로 매번 판단합니다
sql
WHERE EXISTS (
SELECT 1 FROM EMP E2
WHERE E2.DEPTNO = E1.DEPTNO -- 같은 부서
AND E2.SAL > E1.SAL -- 나보다 SAL 높은 사람이 있는가?
)
행별 추적
| E1 행 | 조건 | 내 부서에 나보다 높은 사람? | EXISTS | 출력 |
|---|---|---|---|---|
| ALICE | DEPTNO=10, SAL=5000 | 없음 (BOB=3000) | FALSE | ❌ |
| BOB | DEPTNO=10, SAL=3000 | ALICE=5000 ✅ | TRUE | ✅ |
| CAROL | DEPTNO=20, SAL=4000 | DAVE=4500 ✅ | TRUE | ✅ |
| DAVE | DEPTNO=20, SAL=4500 | 없음 (CAROL=4000) | FALSE | ❌ |
결론
EXISTS = "나(E1 현재 행) 기준으로 조건 만족하는 행이 하나라도 있으면 TRUE"
❌ 사용자 오해: Alice, Dave가 서브쿼리에서 나오면 전체 E1이 TRUE
✅ 실제 동작: Alice 차례엔 "Alice보다 높은 사람 있냐?" → 없으니 FALSE
EXISTS vs IN 비교 — 시험 단골
| 구분 | EXISTS | IN |
|---|---|---|
| 판단 기준 | 행 존재 여부 | 값 포함 여부 |
| NULL 처리 | 영향 없음 | NULL 있으면 오동작 가능 |
| 성능 | 대용량에 유리 | 소용량에 유리 |
| 서브쿼리 결과 | TRUE/FALSE | 실제 값 반환 |
📝 서브쿼리 모드 총정리
스칼라 → SELECT 절, 반드시 1행 1열 반환
인라인뷰 → FROM 절, 가상 테이블처럼 사용
중첩서브쿼리 → WHERE 절, 단일행/다중행 구분 중요
단일행 연산자: =, >, <, >=, <=, <>
다중행 연산자: IN, ANY, ALL, EXISTS
상관 서브쿼리: 외부 쿼리 참조 → 행마다 실행
EXISTS: 행 존재 여부만 판단 → 부서 최고 연봉자 제외 패턴 기억!
✅ 문제모드 완료
다음 순서: [오답노트] 또는 [약점공략] 또는 [최종정리]
준비되면 “다음” 으로 진행하거나, 원하는 모드 말씀해주세요! 💪
You said: 궁금한점
# 궁금한점 Q4에서 중첩서브쿼리부분에서 SELECT 1 FROM EMP E2 WHERE E2.DEPTNO = E1.DEPTNO AND E2.SAL > E1.SAL. 1에 의미가, 0, *과 같지? 그리고, 이해가 안되는게 다음과 같아. emp테이블 e2의 deptno와 e1의 deptno가 같고, e2의 sal이 e1의 sal보다 큰 데이터를 추출하는 거 아니야? 그러면 deptno가 10인 경우 alice가 bob보다 sal이 크니까 alice를 리턴하는 식으로 해야되는거 아니야?
4:43 PM
Claude responded: 질문 1 — SELECT 1 의 의미
상관 서브쿼리의 동작 원리를 명확히 설명하려 시도했다
상관 서브쿼리의 동작 원리를 명확히 설명하려 시도했다
질문 1 — SELECT 1 의 의미
sql
SELECT 1 -- ✅
SELECT 0 -- ✅
SELECT * -- ✅
SELECT 'X' -- ✅
EXISTS 안에서는 모두 동일합니다. EXISTS는 “행이 존재하는가?” 만 판단하고, 값은 신경 안 씁니다. SELECT 1은 관례적으로 쓰는 표현이고, 성능상 *보다 가볍습니다.
질문 2 — 핵심 오해 짚기
“DEPTNO=10에서 ALICE가 BOB보다 크니까 ALICE를 리턴하는 거 아니야?”
정확히 이 부분이 오해 포인트입니다.
상관 서브쿼리는 E1의 현재 행이 기준점입니다
sql
WHERE E2.DEPTNO = E1.DEPTNO
AND E2.SAL > E1.SAL -- ← E1.SAL이 매번 바뀜!
E1이 ALICE 차례일 때:
→ 조건: E2.DEPTNO=10 AND E2.SAL > 5000 (ALICE의 SAL)
→ DEPTNO=10에서 SAL > 5000 인 사람? → 없음
→ 리턴 없음 → EXISTS = FALSE → ALICE 미출력
E1이 BOB 차례일 때:
→ 조건: E2.DEPTNO=10 AND E2.SAL > 3000 (BOB의 SAL)
→ DEPTNO=10에서 SAL > 3000 인 사람? → ALICE(5000) 있음!
→ 리턴 있음 → EXISTS = TRUE → BOB 출력
시각화
[ALICE 차례] [BOB 차례]
E1.SAL = 5000 E1.SAL = 3000
↓ ↓
서브쿼리: SAL > 5000 ? 서브쿼리: SAL > 3000 ?
ALICE 5000 → NO ALICE 5000 → YES ✅
BOB 3000 → NO BOB 3000 → NO
↓ ↓
결과 없음 결과 있음
EXISTS=FALSE EXISTS=TRUE
ALICE 제외 ❌ BOB 출력 ✅
한 줄 요약
EXISTS 서브쿼리의 질문은 항상:
"지금 내(E1) 기준으로, 조건 맞는 행이 어딘가 존재하냐?"
ALICE 기준으로는 → 나(5000)보다 높은 사람이 없음 → FALSE
BOB 기준으로는 → 나(3000)보다 높은 사람(ALICE)이 있음 → TRUE
이해됐으면 “다음” 으로 진행할게요! 🙌
You said: 다음
다음
4:45 PM
Claude responded: 🔥 [약점공략] JOIN — 유형 총정리 + 문제
다음 학습 단계로 JOIN 약점공략 모드 진행 결정
다음 학습 단계로 JOIN 약점공략 모드 진행 결정
🔥 [약점공략] JOIN — 유형 총정리 + 문제
JOIN은 2과목에서 단독 최다 출제 영역입니다. 개념 → 문제 순으로 빠르게 끝냅니다.
📊 JOIN 유형 한눈에 비교
[A 테이블] [B 테이블]
ID ID
-- --
1 1
2 3
3
| JOIN 종류 | 결과 | 핵심 |
|---|---|---|
| INNER JOIN | ID: 1, 3 | 양쪽 모두 일치하는 행만 |
| LEFT OUTER | ID: 1, 2, 3 | A 전체 + B 일치 (없으면 NULL) |
| RIGHT OUTER | ID: 1, 3 | B 전체 + A 일치 (없으면 NULL) |
| FULL OUTER | ID: 1, 2, 3 | 양쪽 전체 (없으면 NULL) |
| CROSS JOIN | 3 × 2 = 6행 | 모든 조합 (카테시안 곱) |
| SELF JOIN | 같은 테이블을 별칭으로 | 계층구조, 비교 |
🔑 핵심 문법 패턴
sql
-- INNER JOIN (가장 기본)
SELECT A.ID, B.ID
FROM A INNER JOIN B ON A.ID = B.ID;
-- LEFT OUTER JOIN
SELECT A.ID, B.ID
FROM A LEFT OUTER JOIN B ON A.ID = B.ID;
-- ORACLE 전용 (+) 문법 ← 시험 출제!
SELECT A.ID, B.ID
FROM A, B
WHERE A.ID = B.ID(+); -- (+)가 붙은 쪽이 NULL 허용 = LEFT OUTER
-- SELF JOIN (직원-관리자 구조)
SELECT E.ENAME, M.ENAME AS 관리자
FROM EMP E, EMP M
WHERE E.MGR = M.EMPNO;
⚠️ 시험 단골 함정
(+) 위치 혼동:
WHERE A.ID = B.ID(+) → A 기준 LEFT OUTER (B쪽에 + 붙음)
WHERE A.ID(+) = B.ID → B 기준 RIGHT OUTER (A쪽에 + 붙음)
암기법: (+)는 "부족한 쪽(NULL 생길 쪽)"에 붙인다
🧩 JOIN 문제 3개 — 바로 풀기
Q1. OUTER JOIN 결과 — 중
sql
[DEPT] [EMP]
DEPTNO DNAME EMPNO DEPTNO
------ ----- ----- ------
10 영업 101 10
20 개발 102 10
30 총무 103 20
sql
SELECT D.DNAME, E.EMPNO
FROM DEPT D LEFT OUTER JOIN EMP E ON D.DEPTNO = E.DEPTNO;
① 2행 출력
② 3행 출력
③ 4행 출력
④ 5행 출력
Q2. Oracle (+) 문법 — 중
아래 SQL과 동일한 결과를 내는 것은?
sql
SELECT A.ID, B.NAME
FROM A, B
WHERE A.ID = B.ID(+);
① FROM A INNER JOIN B ON A.ID = B.ID
② FROM A LEFT OUTER JOIN B ON A.ID = B.ID
③ FROM A RIGHT OUTER JOIN B ON A.ID = B.ID
④ FROM A FULL OUTER JOIN B ON A.ID = B.ID
Q3. SELF JOIN — 상
sql
-- EMP 테이블
-- EMPNO ENAME MGR
-- 100 KING NULL
-- 101 ALICE 100
-- 102 BOB 100
-- 103 CAROL 101
SELECT E.ENAME, M.ENAME AS MGR_NAME
FROM EMP E LEFT OUTER JOIN EMP M ON E.MGR = M.EMPNO;
결과로 올바른 것은?
① 3행 출력 (KING 제외)
② 4행 출력 (KING의 MGR_NAME = NULL)
③ 4행 출력 (KING 포함, MGR_NAME = ‘KING’)
④ 문법 오류 — 같은 테이블 JOIN 불가
1-? 2-? 3-? 형식으로 답 주세요!
You said: 1-2
1-2 2-2 3-2
4:51 PM
Claude responded: 📊 JOIN 약점공략 — 채점 결과
Graded quiz answers and traced database joins
Graded quiz answers and traced database joins
📊 JOIN 약점공략 — 채점 결과
| 문항 | 정답 | 제출 | 결과 |
|---|---|---|---|
| Q1 | ③ | ② | ❌ |
| Q2 | ② | ② | ✅ |
| Q3 | ② | ② | ✅ |
❌ Q1 — LEFT OUTER JOIN 행 수 계산
핵심 오해: 1:N 관계에서 N쪽 행 수만큼 결과가 늘어납니다
[DEPT] [EMP]
DEPTNO DNAME EMPNO DEPTNO
10 영업 ──┬── 101 10
└── 102 10
20 개발 ──── 103 20
30 총무 ──── (없음)
LEFT OUTER JOIN 결과 (DEPT 기준):
DNAME EMPNO
----- -----
영업 101 ← DEPTNO=10, EMP 2명이므로 2행!
영업 102 ←
개발 103 ← DEPTNO=20, EMP 1명
총무 NULL ← DEPTNO=30, EMP 없음 → NULL로 1행 유지
총 4행 → ③
🔥 암기 공식
LEFT OUTER JOIN 결과 행 수
= 왼쪽 테이블 기준으로, 오른쪽과 매칭되는 행 수의 합
(매칭 없으면 NULL로 1행, 매칭 N개면 N행)
❌ 흔한 실수: "DEPT 3행이니까 3행" → 틀림!
✅ 정답 계산: 10번(2행) + 20번(1행) + 30번(1행) = 4행
✅ JOIN 모드 총정리 요약
INNER JOIN → 양쪽 일치만
LEFT OUTER → 왼쪽 전체, 오른쪽 없으면 NULL
(+) 문법 → (+) 붙은 쪽이 NULL 허용 = 반대쪽이 기준
SELF JOIN → 같은 테이블 별칭 2개로 사용 가능
LEFT OUTER 쓰면 최상위(MGR=NULL)도 출력
행 수 계산 → N쪽 매칭 개수 × 1 + 매칭없는 행 × 1
🗺️ 현재 진행 현황
✅ [개념모드] 정규화
✅ [문제모드] 서브쿼리
✅ [약점공략] JOIN
다음 → [약점공략] 윈도우함수 + DECODE/CASE ★★★
준비되면 “다음” 으로! 💪
You said: 다음
다음
4:57 PM
Claude responded: 🔥 [약점공략] 윈도우함수 + DECODE/CASE
다음 주제를 구조화하여 설명할 준비를 마쳤다
다음 주제를 구조화하여 설명할 준비를 마쳤다
🔥 [약점공략] 윈도우함수 + DECODE/CASE
📊 PART 1 — 윈도우 함수
기본 구조
sql
함수명() OVER (
PARTITION BY 그룹기준컬럼 -- 생략 가능 (전체를 하나로)
ORDER BY 정렬기준컬럼 -- 순위/누적 계산 기준
)
순위 함수 3총사 — 반드시 암기
SAL: 5000, 3000, 3000, 2000
RANK() → 1, 2, 2, 4 (동점 건너뜀)
DENSE_RANK() → 1, 2, 2, 3 (동점 안 건너뜀)
ROW_NUMBER() → 1, 2, 3, 4 (무조건 순차)
| 함수 | 동점 처리 | 다음 순위 |
|---|---|---|
| RANK | 같은 순위 | 건너뜀 (1,2,2,4) |
| DENSE_RANK | 같은 순위 | 안 건너뜀 (1,2,2,3) |
| ROW_NUMBER | 순위 없음 | 무조건 순차 (1,2,3,4) |
집계 윈도우 함수
sql
-- 부서별 누적 합계
SELECT ENAME, DEPTNO, SAL,
SUM(SAL) OVER (PARTITION BY DEPTNO ORDER BY SAL) AS 누적합
FROM EMP;
-- 전체 합계 (ORDER BY 없으면 전체 합산)
SELECT ENAME, SAL,
SUM(SAL) OVER () AS 전체합계
FROM EMP;
LAG / LEAD — 자주 출제
sql
LAG(컬럼, N) -- N행 이전 값
LEAD(컬럼, N) -- N행 이후 값
SELECT ENAME, SAL,
LAG(SAL, 1) OVER (ORDER BY SAL) AS 이전SAL,
LEAD(SAL, 1) OVER (ORDER BY SAL) AS 다음SAL
FROM EMP;
-- SAL: 2000, 3000, 5000 순서라면
-- 이전SAL: NULL, 2000, 3000
-- 다음SAL: 3000, 5000, NULL
📊 PART 2 — DECODE / CASE
문법 비교
sql
-- DECODE (Oracle 전용)
DECODE(컬럼, 비교값1, 결과1,
비교값2, 결과2,
기본값)
-- CASE WHEN (ANSI 표준, 모든 DB)
CASE 컬럼
WHEN 비교값1 THEN 결과1
WHEN 비교값2 THEN 결과2
ELSE 기본값
END
-- CASE 검색형 (범위 조건 가능)
CASE
WHEN SAL >= 5000 THEN '고액'
WHEN SAL >= 3000 THEN '중액'
ELSE '저액'
END
🔥 NULL 처리 차이 — 시험 함정
sql
-- GRADE = NULL 인 행이 있을 때:
DECODE(GRADE, NULL, '없음', '기타')
→ ✅ NULL = NULL 로 인식 → '없음' 출력
CASE GRADE WHEN NULL THEN '없음' ELSE '기타' END
→ ❌ NULL = NULL 은 UNKNOWN → ELSE '기타' 출력
-- CASE에서 NULL 처리하려면:
CASE WHEN GRADE IS NULL THEN '없음' ELSE '기타' END ✅
🧩 문제 4개 — 풀기
Q1. 순위 함수 — 중
sql
SELECT ENAME, SAL,
DENSE_RANK() OVER (ORDER BY SAL DESC) AS DR
FROM EMP;
-- SAL 데이터: 5000, 4000, 4000, 3000, 3000, 2000
DR 결과로 올바른 것은?
① 1, 2, 2, 3, 3, 4
② 1, 2, 2, 4, 4, 6
③ 1, 2, 3, 4, 5, 6
④ 1, 2, 2, 3, 3, 5
Q2. PARTITION BY — 중
sql
-- EMP 테이블
-- ENAME DEPTNO SAL
-- ALICE 10 5000
-- BOB 10 3000
-- CAROL 20 4000
-- DAVE 20 4500
SELECT ENAME,
RANK() OVER (PARTITION BY DEPTNO ORDER BY SAL DESC) AS RNK
FROM EMP;
결과로 올바른 것은?
① ALICE=1, BOB=2, CAROL=1, DAVE=2
② ALICE=1, BOB=2, CAROL=2, DAVE=1
③ ALICE=1, BOB=2, CAROL=1, DAVE=1
④ ALICE=1, BOB=1, CAROL=1, DAVE=1
Q3. DECODE — 중
sql
SELECT DECODE(SCORE, 100, 'A',
90, 'B',
'C') AS GRADE
FROM TEST;
-- SCORE 데이터: 100, 90, 80, NULL
출력 결과로 올바른 것은?
① A, B, C, NULL
② A, B, C, C
③ A, B, NULL, NULL
④ A, B, C, C (NULL도 C로 처리)
Q4. CASE 검색형 — 상
sql
SELECT ENAME,
CASE
WHEN SAL >= 5000 THEN '임원'
WHEN SAL >= 3000 THEN '중간'
WHEN SAL >= 3000 THEN '신입' -- ← 주목
ELSE '기타'
END AS 등급
FROM EMP;
SAL=3000인 직원의 등급은?
① 임원
② 중간
③ 신입
④ 기타
1-? 2-? 3-? 4-? 형식으로 답 주세요!
You said: 1-1
1-1 2-2 3-4 4-2
5:02 PM
Claude responded: 📊 윈도우함수 + DECODE/CASE — 채점 결과
Evaluated SQL quiz answers and verified all responses correct
Evaluated SQL quiz answers and verified all responses correct
📊 윈도우함수 + DECODE/CASE — 채점 결과
| 문항 | 정답 | 제출 | 결과 |
|---|---|---|---|
| Q1 | ① | ① | ✅ |
| Q2 | ② | ② | ✅ |
| Q3 | ②/④ | ④ | ✅ |
| Q4 | ② | ② | ✅ |
4/4 만점! 🎉
💡 Q3 — 보충 설명
② 와 ④ 가 동일한 출력이라 제 문제 설계 실수입니다. 핵심 개념만 가져가세요.
DECODE(SCORE, 100, 'A', 90, 'B', 'C')
SCORE = NULL 일 때:
NULL = 100? → NO
NULL = 90? → NO
기본값 'C' → ✅ 출력
즉, NULL은 어떤 값과도 매칭 안 되므로 기본값으로 빠짐
→ NULL도 'C' 출력
💡 Q4 — CASE 핵심 원칙
sql
WHEN SAL >= 3000 THEN '중간'
WHEN SAL >= 3000 THEN '신입' ← 절대 실행 안 됨!
CASE는 위에서 아래로 순서대로 평가하고
첫 번째 TRUE 조건에서 즉시 멈춤
→ 중복 조건이 있어도 먼저 나온 것이 무조건 우선
→ 시험에서 "이 조건은 절대 실행되지 않는다" 유형으로 출제됨
🗺️ 현재 진행 현황
✅ [개념모드] 정규화
✅ [문제모드] 서브쿼리
✅ [약점공략] JOIN
✅ [약점공략] 윈도우함수 + DECODE/CASE
다음 → [약점공략] 트랜잭션/TCL + DDL 특징 ★★☆
이후 → [최종정리] 암기카드 🎯
준비되면 “다음” 으로! 💪
You said: 다음
다음
5:03 PM
Claude responded: 🔥 [약점공략] 트랜잭션 / TCL + DDL
다음 내용을 준비했습니다
다음 내용을 준비했습니다
🔥 [약점공략] 트랜잭션 / TCL + DDL
📊 PART 1 — 명령어 분류 먼저 확정
| 분류 | 명령어 | 설명 |
|---|---|---|
| DDL | CREATE, ALTER, DROP, TRUNCATE, RENAME | 구조 변경 |
| DML | INSERT, UPDATE, DELETE, MERGE | 데이터 조작 |
| TCL | COMMIT, ROLLBACK, SAVEPOINT | 트랜잭션 제어 |
| DCL | GRANT, REVOKE | 권한 제어 |
📊 PART 2 — 트랜잭션 ACID
A (Atomicity) 원자성 — 전부 성공 or 전부 실패
C (Consistency) 일관성 — 트랜잭션 전후 DB 일관성 유지
I (Isolation) 고립성 — 동시 실행 트랜잭션은 서로 영향 없음
D (Durability) 지속성 — COMMIT된 데이터는 영구 보존
📊 PART 3 — TCL 핵심
sql
-- 기본 흐름
INSERT INTO EMP VALUES (101, 'ALICE');
SAVEPOINT SP1; -- 중간 저장점
INSERT INTO EMP VALUES (102, 'BOB');
SAVEPOINT SP2;
INSERT INTO EMP VALUES (103, 'CAROL');
ROLLBACK TO SP1; -- SP1 이후 작업 취소 (BOB, CAROL 삭제)
-- ALICE는 살아있음
COMMIT; -- ALICE만 확정
SAVEPOINT 시각화
[시작]─INSERT ALICE─[SP1]─INSERT BOB─[SP2]─INSERT CAROL
↑
ROLLBACK TO SP1 → SP1 이후 전부 취소
SP1 자체는 유지, ALICE는 살아있음
📊 PART 4 — 🔥 TRUNCATE vs DELETE 최다 출제
| 비교 | TRUNCATE | DELETE |
|---|---|---|
| 분류 | DDL | DML |
| ROLLBACK | ❌ 불가 | ✅ 가능 |
| COMMIT | 자동 COMMIT | 명시적 COMMIT 필요 |
| WHERE 조건 | ❌ 불가 (전체만) | ✅ 가능 |
| 속도 | 빠름 | 느림 |
| 로그 | 최소 로그 | 전체 로그 |
| 트리거 | 미발생 | 발생 |
암기: TRUNCATE = 잘라내기 (DDL, 되돌릴 수 없음)
DELETE = 지우기 (DML, 되돌릴 수 있음)
📊 PART 5 — DDL 자동 COMMIT 주의
sql
INSERT INTO EMP VALUES (101, 'ALICE'); -- 미확정 상태
INSERT INTO EMP VALUES (102, 'BOB'); -- 미확정 상태
DROP TABLE DEPT; -- DDL 실행 순간 자동 COMMIT!
-- 위 INSERT 2개도 함께 COMMIT됨
ROLLBACK; -- 이미 COMMIT됐으므로 아무 효과 없음
🧩 문제 4개 — 풀기
Q1. TRUNCATE vs DELETE — 중
TRUNCATE와 DELETE의 차이로 옳지 않은 것은?
① TRUNCATE는 DDL이고 DELETE는 DML이다
② TRUNCATE는 ROLLBACK이 불가하고 DELETE는 가능하다
③ TRUNCATE는 WHERE 조건으로 일부만 삭제할 수 있다
④ TRUNCATE는 자동 COMMIT이 발생한다
Q2. SAVEPOINT — 중
sql
INSERT INTO T VALUES (1);
SAVEPOINT A;
INSERT INTO T VALUES (2);
SAVEPOINT B;
INSERT INTO T VALUES (3);
ROLLBACK TO A;
INSERT INTO T VALUES (4);
COMMIT;
최종적으로 테이블 T에 남아있는 데이터는?
① 1, 2, 3, 4
② 1, 4
③ 1, 2, 4
④ 4
Q3. DDL 자동 COMMIT — 상
sql
-- 초기 EMP 테이블: 데이터 없음
INSERT INTO EMP VALUES (1, 'ALICE');
INSERT INTO EMP VALUES (2, 'BOB');
TRUNCATE TABLE EMP;
ROLLBACK;
SELECT COUNT(*) FROM EMP;
결과는?
① 0
② 1
③ 2
④ 오류 발생
Q4. 트랜잭션 ACID — 중
트랜잭션의 특성 중 고립성(Isolation) 에 대한 설명으로 옳은 것은?
① 트랜잭션은 전부 실행되거나 전부 취소되어야 한다
② COMMIT된 데이터는 장애 발생 후에도 영구 보존된다
③ 동시에 실행되는 트랜잭션은 서로의 연산에 영향을 받지 않아야 한다
④ 트랜잭션 실행 전후의 데이터베이스 상태는 일관성을 유지해야 한다
1-? 2-? 3-? 4-? 형식으로 답 주세요!
You said: 1-3
1-3 2-2 3-1 4-3
5:11 PM
Claude responded: 📊 트랜잭션/TCL + DDL — 채점 결과
Verified all four answers correctly
Verified all four answers correctly
📊 트랜잭션/TCL + DDL — 채점 결과
| 문항 | 정답 | 제출 | 결과 |
|---|---|---|---|
| Q1 | ③ | ③ | ✅ |
| Q2 | ② | ② | ✅ |
| Q3 | ① | ① | ✅ |
| Q4 | ③ | ③ | ✅ |
4/4 만점! 🎉 완벽합니다!
💡 핵심 개념 재확인 (빠르게)
TRUNCATE = DDL = 자동COMMIT = ROLLBACK 불가 = WHERE 불가
DELETE = DML = 수동COMMIT = ROLLBACK 가능 = WHERE 가능
SAVEPOINT → ROLLBACK TO SP → SP 이후만 취소, 이전은 유지
DDL 실행 → 앞의 미확정 DML까지 전부 자동 COMMIT
🗺️ 전체 진행 현황
✅ [개념모드] 정규화
✅ [문제모드] 서브쿼리
✅ [약점공략] JOIN
✅ [약점공략] 윈도우함수 + DECODE/CASE
✅ [약점공략] 트랜잭션/TCL + DDL
🎯 마지막 → [최종정리] 암기카드
📊 오늘 전체 학습 성과
| 영역 | 진단 | 현재 |
|---|---|---|
| 정규화 | 🔴 취약 | 🟢 개념 완성 |
| 서브쿼리/EXISTS | 🔴 취약 | 🟢 완성 |
| JOIN | 🟢 양호 | 🟢 강화 |
| 윈도우함수 | 🟢 양호 | 🟢 강화 |
| DECODE/CASE | 🟡 보통 | 🟢 완성 |
| TCL/DDL | 🟢 양호 | 🟢 강화 |
준비되면 “다음” — 시험 직전 최종 암기카드로 마무리합니다! 🚀
You said: 다음
다음
5:12 PM
Claude responded: 🎯 [최종정리] 시험 직전 암기카드
사용자 입력이 불완전하여 요약할 수 없습니다
사용자 입력이 불완전하여 요약할 수 없습니다
🎯 [최종정리] 시험 직전 암기카드
내일 시험장 가기 전 이것만 다시 보세요
🃏 CARD 1 — 정규화
1NF → 칸 하나 = 값 하나 (원자값)
2NF → 부분 함수 종속 제거 (복합키 일부에만 종속)
3NF → 이행 함수 종속 제거 (A→B→C 구조)
BCNF → 모든 결정자가 후보키여야 함
⚠️ 2NF는 복합키일 때만 발생
⚠️ 역정규화 = 성능 위해 의도적으로 합치는 것 (나쁜 것 ❌)
🃏 CARD 2 — NULL 처리
sql
NULL 연산 → 결과 항상 NULL (100 + NULL = NULL)
NVL(a, b) → a가 NULL이면 b
NULLIF(a,b) → a = b 이면 NULL, 다르면 a
COALESCE → 첫 번째 NOT NULL 값 반환
WHERE 절 → NULL 비교는 반드시 IS NULL / IS NOT NULL
(= NULL 은 항상 FALSE)
🃏 CARD 3 — JOIN
INNER JOIN → 양쪽 일치만 출력
LEFT OUTER → 왼쪽 전체 + 오른쪽 NULL
RIGHT OUTER → 오른쪽 전체 + 왼쪽 NULL
FULL OUTER → 양쪽 전체 + 없으면 NULL
CROSS JOIN → M × N 행 (카테시안 곱)
SELF JOIN → 같은 테이블 별칭 2개
Oracle (+) 문법:
WHERE A.ID = B.ID(+) → LEFT OUTER (+ 반대쪽이 기준)
🃏 CARD 4 — 서브쿼리
위치별:
SELECT 절 → 스칼라 서브쿼리 (반드시 1행 1열)
FROM 절 → 인라인뷰 (가상 테이블)
WHERE 절 → 중첩 서브쿼리
연산자:
단일행: =, >, <, >=, <=, <>
다중행: IN, ANY, ALL, EXISTS
핵심 암기:
= ANY → IN 과 동일
<> ALL → NOT IN 과 동일 (<> ANY 아님!)
> ALL → MAX보다 크다
> ANY → MIN보다 크다
EXISTS: 행 존재하면 TRUE, 부서 최고연봉자는 제외됨
🃏 CARD 5 — GROUP BY / HAVING
sql
실행 순서: FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY
⚠️ WHERE 절 → 집계함수 사용 불가 (AVG, SUM, COUNT...)
⚠️ HAVING 절 → 집계함수 조건 가능
⚠️ SELECT 별칭 → HAVING에서 사용 불가, ORDER BY에서는 가능
SELECT DEPTNO, AVG(SAL)
FROM EMP
WHERE SAL > 1000 -- 개별 행 조건
GROUP BY DEPTNO
HAVING AVG(SAL) > 3000 -- 그룹 조건
ORDER BY AVG(SAL) DESC;
🃏 CARD 6 — 윈도우 함수
RANK() → 1, 2, 2, 4 (동점 건너뜀)
DENSE_RANK() → 1, 2, 2, 3 (동점 안 건너뜀)
ROW_NUMBER() → 1, 2, 3, 4 (무조건 순차)
PARTITION BY → 그룹 나누기 (GROUP BY와 다르게 행 유지)
LAG(컬럼, N) → N행 이전 값
LEAD(컬럼, N) → N행 이후 값
부서별 1등만 추출 패턴:
SELECT * FROM (
SELECT ..., RANK() OVER (PARTITION BY DEPTNO
ORDER BY SAL DESC) RNK
FROM EMP
) WHERE RNK = 1;
🃏 CARD 7 — DECODE / CASE
sql
DECODE(컬럼, 값1, 결과1, 값2, 결과2, 기본값)
→ Oracle 전용, NULL=NULL 인식 (같다고 봄)
CASE WHEN 조건 THEN 결과 ELSE 기본값 END
→ ANSI 표준, NULL=NULL 인식 안 함
→ 위→아래 순서, 첫 TRUE에서 즉시 멈춤
→ 범위 조건(>=, LIKE 등) 사용 가능
NULL 비교 시:
DECODE(col, NULL, 'X') → ✅ NULL 잡힘
CASE WHEN col IS NULL → ✅ NULL 잡힘
CASE WHEN col = NULL → ❌ 절대 안 잡힘
🃏 CARD 8 — DDL / DML / TCL
DDL (자동 COMMIT, ROLLBACK 불가)
CREATE, ALTER, DROP, TRUNCATE, RENAME
DML (수동 COMMIT, ROLLBACK 가능)
INSERT, UPDATE, DELETE, MERGE
TCL
COMMIT → 확정 (되돌릴 수 없음)
ROLLBACK → 취소
SAVEPOINT → 중간 저장점
TRUNCATE vs DELETE:
TRUNCATE = DDL = 빠름 = ROLLBACK 불가 = WHERE 불가
DELETE = DML = 느림 = ROLLBACK 가능 = WHERE 가능
⚠️ DDL 실행 시 앞의 미확정 DML도 자동 COMMIT됨!
🃏 CARD 9 — 주식별자 / ERD
주식별자 4가지 특징:
유일성 — 모든 인스턴스를 유일하게 구분
최소성 — 구성 속성 수 최소화
불변성 — 값이 자주 변경되면 안 됨
존재성 — NULL 불가
M:N 관계 → 물리 모델에서 직접 구현 불가
→ 교차 엔터티(연결 테이블)로 해소
🃏 CARD 10 — 자주 나오는 함정 모음
❌ WHERE에 집계함수 → HAVING으로
❌ = NULL → IS NULL로
❌ TRUNCATE ROLLBACK 가능 → DDL이라 불가
❌ <> ANY = NOT IN → <> ALL이 NOT IN
❌ 2NF는 단일키에서 발생 → 복합키 전제
❌ SELF JOIN 불가 → 별칭으로 가능
❌ EXISTS는 전체 판단 → 행별 개별 판단
❌ CASE WHEN col = NULL → IS NULL 써야 함
❌ M:N 그대로 구현 가능 → 교차 엔터티 필요
🌙 시험 전날 밤 체크리스트
□ 암기카드 1~10 빠르게 한 번 더 읽기
□ 오답노트 (정규화, EXISTS, DECODE/CASE NULL) 확인
□ 내일 08:30 시험 — 08:00까지 입실
□ 수험표 + 신분증 준비
□ 일찍 자기 (컨디션이 점수)
📊 오늘 최종 학습 요약
| 모드 | 영역 | 점수 |
|---|---|---|
| 진단 | 전 영역 | 7/10 |
| 개념 | 정규화 | 완성 ✅ |
| 문제 | 서브쿼리 | 4/5 ✅ |
| 약점 | JOIN | 2/3 ✅ |
| 약점 | 윈도우/DECODE | 4/4 💯 |
| 약점 | TCL/DDL | 4/4 💯 |
내일 시험 꼭 합격하세요! 💪🎯 긴장되면 CARD 10 함정 모음만 다시 보고 들어가세요!
0 글이 마음에 드시면 하트를 눌러주세요! 행복한 고민이 됩니다!