정보처리기사 실기에서 SQL은 매 회차 반드시 출제되는 핵심 파트입니다. 다행히 나오는 유형이 어느 정도 정해져 있어서, 패턴만 잡으면 확실하게 점수를 챙길 수 있어요. 이 글에서는 실제 시험에 나오는 SQL 유형을 처음부터 차근차근 정리해드릴게요.

📌 실기 SQL 출제 비중
SQL 관련 문제는 실기 배점의 약 20~30%를 차지합니다. DDL·DML·DCL 개념 서술부터 직접 쿼리를 작성하거나 결과를 예측하는 문제까지 다양하게 나옵니다.

📦 SQL 명령어 4가지 분류부터 잡자

SQL은 역할에 따라 4가지로 나뉩니다. 시험에서 "다음 중 DDL에 해당하는 명령어는?" 식으로 분류 자체를 묻는 문제가 자주 나오니까 먼저 외워두세요.

분류 이름 대표 명령어 하는 일
DDL 데이터 정의어 CREATE, ALTER, DROP, TRUNCATE 테이블·구조 생성·수정·삭제
DML 데이터 조작어 SELECT, INSERT, UPDATE, DELETE 데이터 조회·삽입·수정·삭제
DCL 데이터 제어어 GRANT, REVOKE 사용자 권한 부여·회수
TCL 트랜잭션 제어어 COMMIT, ROLLBACK, SAVEPOINT 트랜잭션 확정·취소·저장점
💡 암기 꿀팁
DDL구조를 다루고, DML데이터를 다룹니다. DDL은 자동 COMMIT이 되지만, DML은 명시적으로 COMMIT해야 반영됩니다. 이 차이를 꼭 기억하세요!

🏗️ DDL — 테이블 만들고 바꾸는 명령어

DDL은 테이블의 틀(구조)을 만들거나 수정하는 명령어예요. 직접 쿼리를 쓰라는 문제보다는 문법 빈칸 채우기 형태로 자주 출제됩니다.

CREATE TABLE — 테이블 생성

CREATE TABLE 학생 (
    학번    CHAR(8)      PRIMARY KEY,
    이름    VARCHAR(20)  NOT NULL,
    학과    VARCHAR(30),
    학년    INT          DEFAULT 1,
    성적    FLOAT,
    FOREIGN KEY (학과) REFERENCES 학과정보(학과명)
);
제약조건의미
PRIMARY KEY기본키 — 중복 불가 + NULL 불가
FOREIGN KEY외래키 — 다른 테이블의 기본키 참조
NOT NULLNULL 값 입력 금지
UNIQUE중복 불가 (NULL은 허용)
DEFAULT값을 안 넣으면 자동으로 들어가는 기본값
CHECK특정 조건을 만족하는 값만 허용

ALTER TABLE — 테이블 구조 변경

-- 컬럼 추가
ALTER TABLE 학생 ADD 이메일 VARCHAR(50);

-- 컬럼 타입 변경
ALTER TABLE 학생 MODIFY 이름 VARCHAR(30);

-- 컬럼 삭제
ALTER TABLE 학생 DROP COLUMN 이메일;

-- 제약조건 추가
ALTER TABLE 학생 ADD CONSTRAINT 성적_범위 CHECK (성적 BETWEEN 0 AND 100);

DROP vs TRUNCATE vs DELETE 차이

명령어분류롤백 가능?결과
DROP TABLEDDL❌ 불가테이블 구조 + 데이터 모두 삭제
TRUNCATEDDL❌ 불가데이터만 전체 삭제 (구조는 유지)
DELETEDML✅ 가능조건에 맞는 행만 삭제
🎯 자주 나오는 시험 포인트
"ROLLBACK으로 복구할 수 없는 명령어는?" → DROP, TRUNCATE (DDL은 자동 COMMIT)
"테이블 구조는 남기고 데이터만 전부 지우는 명령어는?" → TRUNCATE

🔍 SELECT — 데이터 조회의 핵심

실기에서 가장 많이 나오는 부분입니다. SELECT 문의 실행 순서와 각 절의 역할을 정확히 이해해야 해요.

SELECT 실행 순서 (이게 제일 중요!)

SQL은 작성 순서와 실제 실행 순서가 다릅니다. 이걸 모르면 GROUP BY, HAVING, WHERE 문제에서 자꾸 틀려요.

① FROM ② WHERE ③ GROUP BY ④ HAVING ⑤ SELECT ⑥ ORDER BY

기억법: "프~ 윙 그 하 셀 오(FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY)"

기본 SELECT 문법

SELECT [DISTINCT] 컬럼1, 컬럼2, ...
FROM   테이블명
WHERE  조건
GROUP BY 그룹기준컬럼
HAVING 그룹조건
ORDER BY 정렬기준 [ASC | DESC];

아래 예시 테이블로 실제 문제 느낌을 익혀봅시다.

📋 학생(STUDENT) 테이블
학번이름학과학년성적
2021001김민준컴퓨터공학388
2021002이서연정보통신292
2022003박지호컴퓨터공학275
2022004최수아소프트웨어195
2023005정우진컴퓨터공학182

WHERE — 조건 필터링

-- 성적이 85점 이상인 학생 조회
SELECT 이름, 성적
FROM   학생
WHERE  성적 >= 85;

-- 컴퓨터공학과이고 학년이 2학년 이상
SELECT *
FROM   학생
WHERE  학과 = '컴퓨터공학' AND 학년 >= 2;

-- 성적이 80~90 사이 (BETWEEN)
SELECT 이름, 성적
FROM   학생
WHERE  성적 BETWEEN 80 AND 90;

-- 학과가 컴퓨터공학 또는 정보통신 (IN)
SELECT 이름, 학과
FROM   학생
WHERE  학과 IN ('컴퓨터공학', '정보통신');

GROUP BY + HAVING — 그룹 집계

GROUP BY는 특정 컬럼 기준으로 행을 묶어서 집계함수(COUNT, SUM, AVG, MAX, MIN)를 적용할 때 씁니다. HAVING은 GROUP BY 이후의 그룹에 조건을 거는 것이고, WHERE는 그룹화 전에 개별 행에 조건을 거는 것입니다.

-- 학과별 학생 수와 평균 성적 조회
SELECT   학과, COUNT(*) AS 학생수, AVG(성적) AS 평균성적
FROM     학생
GROUP BY 학과;

-- 평균 성적이 80점 이상인 학과만 출력 (HAVING 사용)
SELECT   학과, AVG(성적) AS 평균성적
FROM     학생
GROUP BY 학과
HAVING   AVG(성적) >= 80;
🎯 WHERE vs HAVING 헷갈리면 이것만!
WHERE — 개별 행(row)에 조건 → GROUP BY 전에 실행
HAVING — 그룹에 조건 → GROUP BY 후에 실행

"WHERE에는 집계함수를 쓸 수 없다"는 것도 자주 출제됩니다.

집계함수 정리

함수의미NULL 처리
COUNT(*)전체 행 개수NULL 포함
COUNT(컬럼)해당 컬럼 값이 있는 행 개수NULL 제외
SUM(컬럼)합계NULL 제외
AVG(컬럼)평균NULL 제외
MAX(컬럼)최댓값NULL 제외
MIN(컬럼)최솟값NULL 제외

ORDER BY — 정렬

-- 성적 내림차순 정렬 (높은 순)
SELECT 이름, 성적
FROM   학생
ORDER BY 성적 DESC;

-- 학과 오름차순, 같은 학과면 성적 내림차순
SELECT 이름, 학과, 성적
FROM   학생
ORDER BY 학과 ASC, 성적 DESC;

🔗 JOIN — 여러 테이블 합치기

JOIN은 두 개 이상의 테이블을 연결해서 하나의 결과로 보여주는 것입니다. 실기에서 결과 예측이나 쿼리 작성 문제로 자주 나옵니다.

🔵🟢
INNER JOIN
두 테이블 모두 일치하는 행만
🔵⬜
LEFT JOIN
왼쪽 테이블 전체 + 오른쪽 일치 행
⬜🟢
RIGHT JOIN
오른쪽 테이블 전체 + 왼쪽 일치 행
🔵🟢🔵
FULL OUTER JOIN
양쪽 테이블 모두 (불일치는 NULL)

예시로 두 테이블을 만들어 보겠습니다.

📋 수강(ENROLLMENT) 테이블
학번과목코드점수
2021001CS10190
2021002CS10185
2021001CS20278
2099999CS30395
-- INNER JOIN: 학생 테이블과 수강 테이블에서 모두 존재하는 학생만
SELECT S.이름, E.과목코드, E.점수
FROM   학생 S
INNER JOIN 수강 E ON S.학번 = E.학번;

-- LEFT JOIN: 학생 테이블 전체 (수강 안 한 학생도 포함)
SELECT S.이름, E.과목코드, E.점수
FROM   학생 S
LEFT JOIN 수강 E ON S.학번 = E.학번;
🎯 JOIN 결과 예측 문제 풀이 법
1. 기준 테이블이 어딘지 파악 (LEFT면 왼쪽이 기준)
2. ON 조건이 일치하는 행끼리 연결
3. 일치하지 않는 행은 NULL로 채움
4. 위 학번 2099999는 학생 테이블에 없으므로 INNER JOIN 결과에서 제외됨

🪆 서브쿼리 — 쿼리 안의 쿼리

서브쿼리는 SELECT 문 안에 또 다른 SELECT 문이 들어가는 형태입니다. 위치에 따라 이름이 달라지고, 시험에서도 종류를 묻는 문제가 나옵니다.

위치이름특징
WHERE 절중첩 서브쿼리가장 자주 출제. 조건값을 동적으로 구함
FROM 절인라인 뷰서브쿼리 결과를 임시 테이블처럼 사용
SELECT 절스칼라 서브쿼리컬럼 자리에 단일 값 반환

WHERE절 서브쿼리 (가장 자주 출제)

-- 평균 성적보다 높은 학생 조회
SELECT 이름, 성적
FROM   학생
WHERE  성적 > (SELECT AVG(성적) FROM 학생);

-- 컴퓨터공학과 학생 중 최고 성적과 동일한 학생 조회
SELECT 이름, 성적
FROM   학생
WHERE  성적 = (SELECT MAX(성적) FROM 학생 WHERE 학과 = '컴퓨터공학');

IN / ANY / ALL 서브쿼리

-- IN: 서브쿼리 결과 목록 중 하나와 일치
SELECT 이름
FROM   학생
WHERE  학번 IN (SELECT 학번 FROM 수강 WHERE 과목코드 = 'CS101');

-- ALL: 서브쿼리 결과 모두보다 크거나 작은 경우
-- 모든 정보통신과 학생보다 성적이 높은 학생
SELECT 이름, 성적
FROM   학생
WHERE  성적 > ALL (SELECT 성적 FROM 학생 WHERE 학과 = '정보통신');

-- ANY: 서브쿼리 결과 중 하나라도 만족
SELECT 이름, 성적
FROM   학생
WHERE  성적 > ANY (SELECT 성적 FROM 학생 WHERE 학과 = '정보통신');
💡 ANY vs ALL 직관적 이해
ALL은 "전부 다 이겨야 통과" → 최댓값보다 크면 ALL보다 크다
ANY는 "하나만 이겨도 통과" → 최솟값보다 크면 ANY보다 크다

> ALL> MAX(서브쿼리)
> ANY> MIN(서브쿼리)

FROM절 서브쿼리 — 인라인 뷰

-- 학과별 평균 성적을 구한 뒤, 평균이 85 이상인 학과만 출력
SELECT 학과, 평균성적
FROM   (SELECT 학과, AVG(성적) AS 평균성적
        FROM   학생
        GROUP BY 학과) AS 학과별평균
WHERE  평균성적 >= 85;

🔐 DCL — 권한 관리

DCL은 사용자에게 권한을 주거나 뺏는 명령어입니다. 개념 암기 위주로 출제됩니다.

-- GRANT: 권한 부여
GRANT SELECT, INSERT ON 학생 TO 홍길동;
GRANT ALL ON 학생 TO 홍길동 WITH GRANT OPTION;
--         ↑ WITH GRANT OPTION: 홍길동이 다른 사람에게 권한을 재부여할 수 있음

-- REVOKE: 권한 회수
REVOKE SELECT ON 학생 FROM 홍길동;
REVOKE SELECT ON 학생 FROM 홍길동 CASCADE;
--                             ↑ CASCADE: 홍길동이 부여한 다른 사람 권한도 함께 회수
옵션의미
WITH GRANT OPTION받은 권한을 다른 사용자에게 재부여 가능
CASCADE권한 회수 시 연쇄적으로 재부여된 권한도 회수

🔄 TCL — 트랜잭션 제어

트랜잭션은 하나의 논리적 작업 단위입니다. 은행 이체처럼 "전부 되거나 전부 안 되거나"를 보장하는 개념이에요.

-- 작업 확정
COMMIT;

-- 작업 취소 (마지막 COMMIT 시점으로 되돌아감)
ROLLBACK;

-- 저장점 설정 후 부분 취소
SAVEPOINT sp1;
-- ... 작업 ...
ROLLBACK TO sp1;  -- sp1 이후 작업만 취소
🎯 트랜잭션 4가지 특성 (ACID)
원자성(Atomicity) — 전부 실행되거나 전부 취소
일관성(Consistency) — 트랜잭션 전후 데이터 일관성 유지
격리성(Isolation) — 다른 트랜잭션에 영향 받지 않음
지속성(Durability) — COMMIT된 결과는 영구 반영

🧩 실전 문제 풀어보기

위에서 배운 내용을 종합해서 아래 문제를 풀어보세요.

📝 문제 1
학생 테이블에서 학과별 학생 수를 구하되, 학생 수가 2명 이상인 학과의 학과명과 학생 수를 학생 수 내림차순으로 출력하시오.
-- 정답
SELECT   학과, COUNT(*) AS 학생수
FROM     학생
GROUP BY 학과
HAVING   COUNT(*) >= 2
ORDER BY 학생수 DESC;
📝 문제 2
학생 테이블에서 이름과 성적을 조회하되, 자신이 속한 학과의 평균 성적보다 높은 학생만 출력하시오.
-- 정답 (상관 서브쿼리)
SELECT 이름, 성적, 학과
FROM   학생 A
WHERE  성적 > (SELECT AVG(성적)
               FROM   학생 B
               WHERE  B.학과 = A.학과);
📚 정리 — SQL 실기 고득점 전략 3가지

① SELECT 실행 순서를 암기하세요. FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY. 이걸 모르면 HAVING과 WHERE 문제를 계속 틀립니다.

② WHERE vs HAVING 구분을 확실히 하세요. 집계함수가 조건에 있으면 HAVING, 없으면 WHERE입니다.

③ JOIN 결과는 직접 표를 그려서 확인하는 연습을 하세요. 머릿속으로 계산하려다가 실수하는 경우가 많습니다. 시험지 여백에 테이블 그리는 습관을 들이세요.