CREATE TABLE 학생 (
학번 VARCHAR(10) PRIMARY KEY,
이름 VARCHAR(20) NOT NULL,
이메일 VARCHAR(50) UNIQUE,
나이 INTCHECK (나이 >= 0 AND 나이 <= 150),
학과번호 INTREFERENCES 학과(학과번호)
ON DELETE CASCADEON UPDATE CASCADE,
입학년도 INTDEFAULT 2024,
CONSTRAINT pk_학생 PRIMARY KEY (학번)
);
제약조건
설명
PRIMARY KEY
기본키 (NOT NULL + UNIQUE 자동 적용)
NOT NULL
NULL 입력 불가
UNIQUE
중복 불가 (NULL은 허용)
CHECK (조건)
도메인 제약 (입력값 범위/조건)
REFERENCES 테이블(열)
외래키 참조 무결성
DEFAULT 값
미입력 시 기본값
ON DELETE CASCADE
참조 행 삭제 시 함께 삭제
ON DELETE SET NULL
참조 행 삭제 시 NULL로
ALTER TABLE
✏️
ALTER TABLE
자주출제
-- 열 추가ALTER TABLE 학생 ADD 전화번호 VARCHAR(15);
-- 열 수정 (Oracle: MODIFY, SQL Server: ALTER COLUMN)ALTER TABLE 학생 MODIFY 이름 VARCHAR(30) NOT NULL;
-- 열 삭제ALTER TABLE 학생 DROP COLUMN 전화번호;
-- 제약조건 추가ALTER TABLE 학생 ADD CONSTRAINT fk_학과
FOREIGN KEY (학과번호) REFERENCES 학과(학과번호);
-- 제약조건 삭제ALTER TABLE 학생 DROP CONSTRAINT fk_학과;
DELETE vs TRUNCATE vs DROP
🗑️
DELETE vs TRUNCATE vs DROP
매회출제
구분
DELETE
TRUNCATE
DROP
분류
DML
DDL
DDL
삭제 대상
행(데이터)
전체 행(데이터)
테이블 전체
WHERE 조건
✅ 가능
❌ 불가
❌ 불가
ROLLBACK
✅ 가능
❌ 불가
❌ 불가
테이블 구조
유지
유지
삭제
로그 기록
행별 기록
최소 기록
—
속도
느림
빠름
—
인덱스 DDL
📑
CREATE / DROP INDEX
자주출제
-- 인덱스 생성CREATE [UNIQUE] INDEX idx_이름
ON 학생 (이름);
-- 복합 인덱스CREATE INDEX idx_복합
ON 학생 (학과번호, 이름);
-- 인덱스 삭제DROP INDEX idx_이름;
인덱스 특징
내용
장점
SELECT 속도 향상 (검색 성능↑)
단점
INSERT·UPDATE·DELETE 성능 저하 / 추가 저장공간 필요
UNIQUE 인덱스
중복값 입력 시 오류 발생
SELECT 전체 구조 + 실행 순서
🔍
SELECT 전체 구조 + 실행 순서
매회출제
SELECT [DISTINCT] 컬럼1, 컬럼2, 집계함수 AS 별칭
FROM 테이블명 [AS 별칭]
[WHERE 행 조건]
[GROUP BY 그룹 기준 열]
[HAVING 그룹 조건]
[ORDER BY 정렬 기준 [ASC|DESC]]
[LIMIT 행 수];
실행 순서: ① FROM → ② WHERE → ③ GROUP BY → ④ HAVING → ⑤ SELECT → ⑥ ORDER BY
HAVING은 집계 후 그룹 조건 / WHERE는 집계 전 개별 행 조건
WHERE 조건 상세
🔤
WHERE 조건 상세
자주출제
-- LIKE 패턴 매칭WHERE 이름 LIKE'김%'-- 김으로 시작WHERE 이름 LIKE'%철%'-- 철 포함WHERE 이름 LIKE'김_수'-- 김?수 (? = 한 글자)-- NULL 체크 (= NULL은 오류!)WHERE 점수 IS NULLWHERE 점수 IS NOT NULL-- 범위 (경계값 포함)WHERE 나이 BETWEEN 20 AND 30
-- 목록WHERE 학과 IN ('컴퓨터', '전자', '기계')
WHERE 학과 NOT IN ('국어', '수학')
-- 복합 조건WHERE 나이 >= 20 AND 학과 = '컴퓨터'WHERE 나이 < 20 OR 성적 = 'A'
집계함수 + NULL 처리
∑
집계함수 + NULL 처리
매회출제
함수
설명
NULL 처리
COUNT(*)
전체 행 수
NULL 포함
COUNT(열)
해당 열 값 있는 행 수
NULL 제외
SUM(열)
합계
NULL 무시
AVG(열)
평균
NULL 제외 후 계산 (≠ 전체 합/전체 행)
MAX(열)
최대값
NULL 무시
MIN(열)
최소값
NULL 무시
AVG(점수) = SUM(점수) / COUNT(점수) — NULL 행은 분모에서 제외됨!
-- 학과별 인원 수, 평균 성적 (2학년 이상, 3명 이상인 학과만)SELECT 학과, COUNT(*) AS 인원, AVG(성적) AS 평균
FROM 학생
WHERE 학년 >= 2
GROUP BY 학과
HAVINGCOUNT(*) >= 3
ORDER BY 평균 DESC;
DISTINCT와 ORDER BY
🔢
DISTINCT와 ORDER BY
자주출제
-- 중복 제거SELECT DISTINCT 학과 FROM 학생;
-- 정렬 (기본: ASC 오름차순)SELECT * FROM 학생 ORDER BY 성적 DESC, 이름 ASC;
-- NULL 값은 ORDER BY에서 보통 맨 마지막 (Oracle은 맨 앞)
JOIN 종류
🔗
JOIN 종류
매회출제
종류
결과
특징
INNER JOIN
양쪽 조건 일치하는 행만
가장 일반적인 조인
LEFT OUTER JOIN
왼쪽 전체 + 오른쪽 일치 (없으면 NULL)
왼쪽 기준
RIGHT OUTER JOIN
오른쪽 전체 + 왼쪽 일치 (없으면 NULL)
오른쪽 기준
FULL OUTER JOIN
양쪽 모두 전체
양쪽 NULL 포함
CROSS JOIN
모든 조합 (카르테시안 곱)
행수 = R1 × R2
NATURAL JOIN
동일 속성명으로 자동 동등 조인
중복 열 제거
-- INNER JOINSELECT A.이름, B.과목명, B.성적
FROM 학생 A INNER JOIN 수강 B ON A.학번 = B.학번;
-- LEFT OUTER JOIN (수강 안 한 학생도 포함)SELECT A.이름, B.과목명
FROM 학생 A LEFT OUTER JOIN 수강 B ON A.학번 = B.학번;
-- CROSS JOIN (3명 학생 × 4개 과목 = 12행)SELECT * FROM 학생 CROSS JOIN 과목;
서브쿼리
📦
서브쿼리
자주출제
위치
이름
설명
WHERE절
중첩 서브쿼리
IN, EXISTS, 비교 연산자와 함께 사용
FROM절
인라인 뷰
서브쿼리 결과를 테이블처럼 사용
SELECT절
스칼라 서브쿼리
단일 값 반환
-- IN 서브쿼리 (수강 학생만)SELECT 이름 FROM 학생
WHERE 학번 IN (SELECT 학번 FROM 수강);
-- EXISTS (수강 기록 있는 학생)SELECT 이름 FROM 학생 A
WHERE EXISTS (SELECT 1 FROM 수강 B WHERE A.학번 = B.학번);
-- 스칼라 서브쿼리 (단일값)SELECT 이름, (SELECTMAX(성적) FROM 수강) AS 최고점
FROM 학생;
-- 인라인 뷰 (FROM절 서브쿼리)SELECT * FROM (
SELECT 학번, AVG(성적) AS 평균
FROM 수강 GROUP BY 학번
) AS 평균테이블
WHERE 평균 >= 80;
집합 연산자
∪
집합 연산자
자주출제
연산자
설명
중복 처리
UNION
합집합
중복 제거
UNION ALL
합집합
중복 포함
INTERSECT
교집합
중복 제거
MINUS / EXCEPT
차집합 (첫 번째만)
중복 제거
-- 2학년 OR 컴퓨터과 학생 (합집합)SELECT 학번 FROM 학생 WHERE 학년=2
UNIONSELECT 학번 FROM 학생 WHERE 학과='컴퓨터';
-- 2학년 AND 컴퓨터과 (교집합)SELECT 학번 FROM 학생 WHERE 학년=2
INTERSECTSELECT 학번 FROM 학생 WHERE 학과='컴퓨터';
DML — INSERT · UPDATE · DELETE
✍️
DML — INSERT · UPDATE · DELETE
자주출제
-- INSERT: 모든 열INSERT INTO 학생 VALUES ('S001', '홍길동', '컴퓨터', 2024);
-- INSERT: 특정 열INSERT INTO 학생(학번, 이름) VALUES ('S002', '김철수');
-- INSERT: 다른 테이블에서INSERT INTO 졸업생 SELECT * FROM 학생 WHERE 학년=4;
-- UPDATEUPDATE 학생 SET 학년=학년+1, 학과='전자'WHERE 학번='S001';
-- DELETE (WHERE 없으면 전체 삭제!)DELETE FROM 학생 WHERE 학번='S001';
DCL — GRANT / REVOKE
🔑
DCL — GRANT / REVOKE
매회출제
-- 권한 부여GRANTSELECT, INSERT, UPDATE ON 학생
TO 홍길동;
-- 재부여 권한 포함GRANTSELECT ON 학생
TO 홍길동 WITH GRANT OPTION;
-- 권한 취소REVOKESELECT ON 학생
FROM 홍길동;
-- CASCADE: 홍길동이 재부여한 권한까지 연쇄 취소REVOKESELECT ON 학생
FROM 홍길동 CASCADE;
옵션
설명
WITH GRANT OPTION
받은 권한을 타인에게 재부여 가능
CASCADE
REVOKE 시 연쇄 취소 (재부여받은 사람 권한도 취소)
TCL — 트랜잭션 제어
💾
TCL — 트랜잭션 제어
자주출제
-- 트랜잭션 확정 (영구 반영)COMMIT;
-- 트랜잭션 전체 취소ROLLBACK;
-- 중간 저장점 설정SAVEPOINT sp1;
-- 특정 저장점으로 부분 롤백ROLLBACK TO sp1;
DDL (CREATE, DROP, ALTER)은 자동 COMMIT → ROLLBACK 불가!
뷰 (VIEW)
👁️
뷰(VIEW)
매회출제
하나 이상의 테이블로 유도된 가상 테이블 / 물리적 저장 안됨
항목
내용
장점
보안성 향상 / 논리적 독립성 / 단순화
단점/제약
ALTER 명령으로 구조 변경 불가 / 삽입·수정·삭제 제한적
DML
단순 뷰는 가능, 복합 뷰(GROUP BY, JOIN 포함)는 제한
-- 뷰 생성CREATE VIEW 컴퓨터학생 ASSELECT 학번, 이름 FROM 학생 WHERE 학과='컴퓨터';
-- 뷰 교체 (없으면 생성, 있으면 수정)CREATE OR REPLACE VIEW 컴퓨터학생 AS ...;
-- 뷰 삭제DROP VIEW 컴퓨터학생;
DROP VIEW 컴퓨터학생 CASCADE; -- 의존 뷰도 함께 삭제
뷰는 ALTER로 수정 불가 → CREATE OR REPLACE VIEW 사용
트리거 (TRIGGER)
⚡
트리거(TRIGGER)
자주출제
테이블 이벤트(INSERT·UPDATE·DELETE) 발생 시 자동 실행되는 저장 프로시저
CREATE TRIGGER 급여이력관리
AFTER UPDATE ON 직원
FOR EACH ROWBEGIN-- NEW: 변경 후 값 / OLD: 변경 전 값IF NEW.급여 <> OLD.급여 THENINSERT INTO 급여이력(직원번호, 이전급여, 신급여, 변경일)
VALUES(NEW.직원번호, OLD.급여, NEW.급여, NOW());
END IF;
END;
옵션
설명
BEFORE
이벤트 실행 전 트리거 수행
AFTER
이벤트 실행 후 트리거 수행
NEW
변경 후 (새로운) 행 데이터 참조
OLD
변경 전 (이전) 행 데이터 참조
FOR EACH ROW
행 단위로 트리거 실행
저장 프로시저 · 함수 비교
📦
저장 프로시저·함수·트리거 비교
자주출제
구분
저장 프로시저
함수(Function)
트리거
반환값
없거나 여러 개
반드시 1개 반환
없음
호출
CALL 또는 EXEC
SELECT/표현식 안에서
이벤트 발생 시 자동
사용
복잡한 비즈니스 로직
값 계산·변환
자동화 작업
CREATE PROCEDURE학과별조회(IN 학과명 VARCHAR(20))
BEGINSELECT * FROM 학생 WHERE 학과 = 학과명;
END;
-- 호출CALL학과별조회('컴퓨터');