문서 읽는 데 47분 · 27강 · 3과목 · 데이터베이스 구축

DML

목차 22
전체 59강 중 27강 · 3과목 · 데이터베이스 구축

26강이 테이블을 만들고(DDL) 다스리는(DCL) 명령어였다면, 27강은 그 테이블 안의 데이터를 직접 조회·삽입·수정·삭제(DML) 하는 SQL이다. SQL 응용 단원의 킬러 무대 — 점수밭은 SELECT 6절 처리 순서 · WHERE vs HAVING · 집계 함수 NULL 처리 · JOIN 결과 행 수 · 다중행 서브쿼리. 25강 관계대수(SPJD)가 여기서 실제 SQL로 변신한다.

핵심 암기: DML 4종 SIUD(SELECT·INSERT·UPDATE·DELETE) · 처리 순서 프위그해셀오(FROM·WHERE·GROUP BY·HAVING·SELECT·ORDER BY) · 집계 함수 조건은 무조건 HAVING · COUNT(*)=NULL 포함 / COUNT(컬럼)=NULL 제외 · σ↔WHERE·π↔SELECT·⋈↔JOIN·÷↔HAVING COUNT · DELETE만 DML·ROLLBACK✅


DML 개요

DML 4종 — SELECT · INSERT · UPDATE · DELETE ·DML 분류·1순위·

[정의] DML(Data Manipulation Language, 데이터 조작어)은 테이블 안의 데이터를 다루는 SQL. 구조(스키마)를 다루는 DDL과 갈린다.

[표] DML 4대 명령어.

명령어 기능 한 줄
SELECT 조회 원하는 데이터 검색
INSERT 삽입 새 데이터 추가
UPDATE 수정 기존 데이터 변경
DELETE 삭제 특정 데이터 삭제

🔑 암기 SIUD = 셀·인·업·델(SELECT·INSERT·UPDATE·DELETE). DML의 결정적 특성 = ROLLBACK 가능 ✅ — 트랜잭션 단위로 처리돼 되돌릴 수 있다(DDL은 자동 COMMIT이라 ROLLBACK ❌).

⚠️ 함정 ALTER·TRUNCATE·DROP·CREATE는 DDL / GRANT·REVOKE는 DCL / COMMIT·ROLLBACK·SAVEPOINT는 TCL(명령어 종류 표 기준·26강 회색지대). 특히 ALTER·TRUNCATE를 DML로 착각하는 함정이 단골.

🎯 빈출 "DML 명령어가 아닌 것" — ALTER 같은 DDL 한 개를 섞어 오답 유도. 거의 매회.

💡 보충 21강 정조제 회수 — 정(DDL)·조(DML·27강)·제(DCL)·트(TCL). 26강의 DELETE vs TRUNCATE도 결국 "DELETE만 DML" 한 줄로 갈린다.


SELECT — 데이터 조회

SELECT 6절 구조와 FROM 절 ·SELECT 구조·

[정의] SELECT는 DML에서 가장 복잡한 명령어. 6개 절로 이루어지고, 작성 순서는 아래 고정이다(★실행 순서는 다름 — 처리 순서 카드에서★).

SQL
SELECT   컬럼명               -- 조회할 컬럼
FROM     테이블명             -- 대상 테이블
WHERE    조건                 -- 행 필터링
GROUP BY 그룹화컬럼           -- 그룹화 기준
HAVING   그룹조건             -- 그룹 필터링
ORDER BY 정렬컬럼 [ASC|DESC]  -- 정렬

[표] FROM 절 — 데이터를 가져올 테이블 지정.

형태 의미
단일 테이블 FROM employee 한 테이블 조회
다중 테이블 FROM employee, department 카티션 곱(25강 ×)
별칭(Alias) FROM employee e 또는 ... AS e 긴 테이블명 축약

🔑 암기 SELECT * = 모든 컬럼. 별칭은 테이블명 별칭 또는 테이블명 AS 별칭 — 긴 이름을 줄이고 다중 테이블 조인 시 컬럼 출처를 명확히 한다.

🎯 빈출 6절의 작성 순서·별칭 문법. 보통.

💡 보충 FROM employee, department처럼 테이블을 쉼표로 나열하면 25강 카티션 곱(×)이 일어난다 — WHERE로 조인 조건을 걸지 않으면 두 테이블 행 수의 곱만큼 결과가 폭증한다.

WHERE 절 — 비교 · 논리 · 범위 · 패턴 연산자 ·WHERE·1순위·

[정의] WHERE는 조회할 행(튜플)의 조건을 지정. 관계대수의 Select(σ) 에 대응한다(25강).

[표] WHERE 연산자.

분류 연산자 설명
비교 = <>(≠) > >= < <= 값 비교
논리 AND OR NOT 조건 결합
범위 BETWEEN A AND B A 이상 B 이하(양 끝 포함)
목록 IN (값1, 값2, …) 목록 중 하나
패턴 LIKE '패턴' 문자열 패턴 매칭

[표] LIKE 와일드카드 — 시험 단골.

기호 의미
% 0개 이상의 임의 문자
_ 정확히 1개의 임의 문자

🔑 암기 LIKE '김%' = 김으로 시작 / LIKE '%민%' = 민 포함 / LIKE '김_준' = 3글자·김으로 시작·준으로 끝(_가 정확히 한 글자). BETWEEN 4000 AND 6000 = >= 4000 AND <= 6000(양 끝 포함).

⚠️ 함정 IN ('A','B') = =A OR =B로 같음 / _를 "0개 이상"으로 착각 ❌(→ _정확히 1글자, "0개 이상"은 %).

🎯 빈출 LIKE '김_준'의 의미·%/_ 구분. 거의 매회.

WHERE 절 — NULL 처리 ·WHERE NULL·1순위·

[정의] NULL = 값이 존재하지 않음(0이나 공백과 다름). NULL과 어떤 값을 비교해도 결과는 NULL(알 수 없음) 이라, 일반 비교 연산자(=)로는 걸러지지 않는다.

SQL
SELECT * FROM employee WHERE dept_code IS NULL;       -- NULL인 행
SELECT * FROM employee WHERE dept_code IS NOT NULL;   -- NULL 아닌 행
SELECT salary + COALESCE(bonus, 0) FROM employee;     -- NULL을 0으로 치환

🔑 암기 NULL 비교는 무조건 IS NULL / IS NOT NULL. NULL이 낀 산술 연산(salary + bonus)은 결과도 NULLCOALESCEIFNULL로 치환한다.

⚠️ 함정 WHERE dept_code = NULL ❌(→ 항상 거짓·IS NULL이 정답) / WHERE dept_code == NULL ❌(SQL에 == 없음·문법 오류).

🎯 빈출 NULL 비교 연산자·NULL 산술 결과. 거의 매회(집계 함수 NULL 처리와 짝).

GROUP BY 절 — 행 그룹화 ·GROUP BY·

[정의] GROUP BY는 특정 컬럼 값을 기준으로 행을 묶어 그룹 단위 집계를 가능하게 한다.

SQL
SELECT dept_code, COUNT(*) AS 인원수
FROM employee
GROUP BY dept_code;

🔑 암기 SELECT 절에는 GROUP BY에 명시한 컬럼 또는 집계 함수만 올 수 있다. GROUP BY에 없는 일반 컬럼을 SELECT에 쓰면 오류.

⚠️ 함정 SELECT dept_code, emp_name, COUNT(*) … GROUP BY dept_code ❌(→ emp_name이 GROUP BY에 없어 오류). 그룹을 대표하는 값(집계)만 뽑아야 한다.

🎯 빈출 GROUP BY에 없는 컬럼을 SELECT에 쓴 오류 찾기. 보통.

집계 함수 5종 — COUNT · SUM · AVG · MAX · MIN ·집계 함수·1순위·

[정의] 집계 함수(Aggregate Function)는 여러 행을 하나의 값으로 요약한다. GROUP BY와 짝을 이루지만, GROUP BY 없이 전체를 한 그룹으로 집계할 수도 있다.

[표] 5종 + NULL 처리(★시험 핵심★).

함수 기능 NULL 처리
COUNT(*) 전체 행 수 NULL 포함해서 셈
COUNT(컬럼) 그 컬럼의 NULL 아닌 값 수 NULL 제외
SUM(컬럼) 합계 NULL 무시
AVG(컬럼) 평균 NULL 제외하고 계산
MAX·MIN(컬럼) 최대·최소 NULL 무시

🔑 암기 COUNT(*)만 NULL 포함(전체 행 수), 나머지(COUNT(컬럼)·SUM·AVG·MAX·MIN)는 NULL 제외. AVG는 NULL을 0으로 보지 않고 분모에서 빼고 계산한다.

⚠️ 함정 COUNT(*) vs COUNT(컬럼) 뒤바꿈 — bonus가 [500, NULL, 300, NULL]이면 COUNT(*)=4·COUNT(bonus)=2. "AVG는 NULL을 0으로 계산" ❌(→ NULL 제외).

🎯 빈출 COUNT(*)/COUNT(컬럼) 결과 수·AVG의 NULL 제외. 거의 매회.

HAVING 절 — WHERE vs HAVING ·HAVING·1순위·

[정의] HAVING은 GROUP BY로 묶인 그룹에 조건을 건다. WHERE가 개별 행을 거른다면, HAVING은 집계된 그룹을 거른다.

[표] WHERE vs HAVING — 가장 헷갈리는 1순위.

구분 WHERE HAVING
적용 대상 개별 행(튜플) 그룹
위치 GROUP BY GROUP BY
집계 함수 ❌ 사용 불가 ✅ 사용 가능
처리 시점 그룹화 그룹화
SQL
SELECT dept_code, COUNT(*) AS 인원수, AVG(salary) AS 평균연봉
FROM employee
WHERE hire_date >= '2020-01-01'   -- 개별 행 조건(그룹화 전)
GROUP BY dept_code
HAVING COUNT(*) >= 2;             -- 그룹 조건(그룹화 후·집계 함수)

🔑 암기 집계 함수(COUNT·SUM·AVG·MAX·MIN) 조건은 무조건 HAVING. 일반 컬럼 조건은 WHERE. 처리 순서로 보면 WHERE는 그룹화 전(집계값이 아직 없음), HAVING은 그룹화 후(집계값 계산됨) — 집계 조건이 의미 있는 자리는 HAVING뿐.

⚠️ 함정 WHERE COUNT(*) >= 3 ❌(→ HAVING COUNT(*) >= 3) — 집계 함수를 WHERE에 쓰면 문법 오류. 시험에 SQL 한 줄을 주고 "오류 있는 절"을 묻는 형태로 단골 출제.

🎯 빈출 집계 함수 조건의 올바른 절(HAVING)·WHERE/HAVING 위치. 거의 매회.

💡 보충 25강 매핑 — WHERE는 σ(Select·행 거르기) 자리, HAVING은 ÷(Division·"모든" 조건) 계열로 GROUP BY COUNT와 함께 쓰인다.

ORDER BY와 DISTINCT ·정렬·중복 제거·

[정의] ORDER BY = 결과 정렬, DISTINCT = 중복 행 제거. 둘 다 SELECT 결과를 다듬는 절이다.

SQL
SELECT * FROM employee ORDER BY salary DESC;        -- 내림차순
SELECT * FROM employee ORDER BY dept_code ASC, salary DESC;  -- 다중 키
SELECT DISTINCT dept_code FROM employee;            -- 중복 제거

🔑 암기 ASC=오름차순(기본값·생략 가능) / DESC=내림차순. ORDER BY 2는 SELECT의 2번째 컬럼 기준 정렬. DISTINCT는 반드시 SELECT 바로 뒤 — 25강 π(Project)의 자동 중복 제거에 대응한다.

⚠️ 함정 SELECT dept_code, DISTINCT … ❌(→ DISTINCT는 SELECT 바로 뒤 한 번만) / "ORDER BY 기본값은 DESC" ❌(→ ASC).

🎯 빈출 ASC/DESC 기본값·DISTINCT 위치. 보통.

★ SELECT 6절 처리 순서 — 프위그해셀오 ★ ·처리 순서·최고 빈출·

[정의] SELECT 문은 작성 순서(SELECT 먼저)와 실제 처리(실행) 순서(FROM 먼저)가 다르다. 이 강 전체에서 가장 자주 나오는 단골이다.

[표] 실행 처리 순서.

순서 역할
1 FROM 테이블 지정
2 WHERE 행 필터링
3 GROUP BY 그룹화
4 HAVING 그룹 필터링
5 SELECT 컬럼 선택
6 ORDER BY 정렬

[흐름] 복합 쿼리 한 줄이 처리되는 길 — 작성은 SELECT부터지만, 엔진은 FROM부터 읽는다.

텍스트
 작성 순서:  SELECT  FROM  WHERE  GROUP BY  HAVING  ORDER BY
 처리 순서:  FROM  WHERE  GROUP BY  HAVING  SELECT  ORDER BY
             (1)     (2)      (3)        (4)      (5)      (6)
             테이블  행필터   그룹화    그룹필터  컬럼선택  정렬

🔑 암기 프위그해셀오 — 프롬(FROM)·위어(WHERE)·그룹바이(GROUP BY)·해빙(HAVING)·셀렉트(SELECT)·오더바이(ORDER BY). SELECT가 5번째인 이유 = 어떤 컬럼을 골라낼지는 행이 다 정해진 다음에야 의미가 있어서.

⚠️ 함정 "SELECT가 가장 먼저 처리" ❌(→ 5번째) / "WHERE이 FROM보다 먼저" ❌(→ FROM 없이는 거를 대상이 없음) / "ORDER BY가 GROUP BY보다 먼저" ❌(→ 정렬은 마지막).

🎯 빈출 "각 절이 처리되는 순서로 옳은 것" — 보기 4개 중 프위그해셀오 순서 고르기. 매 회차 1순위.

💡 보충 실전 복합 쿼리도 이 순서로 따라가면 결과가 보인다 — ① FROM으로 데이터 로드 → ② WHERE로 행 거르기 → ③ GROUP BY로 묶기 → ④ HAVING으로 그룹 거르기 → ⑤ SELECT로 컬럼/집계 뽑기 → ⑥ ORDER BY로 정렬.


서브쿼리

서브쿼리 — 단일행 · 다중행 · 위치 ·서브쿼리·1순위·

[정의] 서브쿼리(SubQuery)는 SQL 문 안에 포함된 또 다른 SELECT 문. 바깥 쿼리(메인 쿼리)가 안쪽 쿼리(서브쿼리) 결과를 받아 처리한다.

[표] 반환 행 수에 따른 분류 — 연산자가 갈린다.

종류 반환 연산자
단일행 서브쿼리 1행 1열 = <> > <
다중행 서브쿼리 여러 행 IN · ANY · ALL · EXISTS

[표] 들어가는 위치별 이름.

위치 이름
WHERE 절 조건 비교(가장 흔함)
FROM 절 인라인 뷰(Inline View)
SELECT 절 스칼라 서브쿼리
SQL
-- 다중행 서브쿼리: 부서별 최고 연봉과 같은 직원
SELECT emp_name, salary
FROM employee
WHERE salary IN (SELECT MAX(salary) FROM employee GROUP BY dept_code);

🔑 암기 단일행 = = 계열 / 다중행 = IN·ANY·ALL·EXISTS. 서브쿼리가 여러 행을 반환하는데 =로 비교하면 오류 — IN을 써야 한다.

⚠️ 함정 다중행 반환 서브쿼리에 단일행 연산자(=) 사용 ❌ / EXISTS는 행의 존재 여부만 보고 참/거짓을 반환(값 비교가 아님).

🎯 빈출 복잡한 중첩 서브쿼리를 주고 반환되는 튜플 수를 묻는 킬러. IN/EXISTS가 핵심.


INSERT · UPDATE · DELETE

INSERT — 데이터 삽입 ·INSERT·

[정의] 테이블에 새 행을 추가하는 명령어. 세 가지 형태가 있다.

SQL
-- ① 전체 컬럼에 순서대로
INSERT INTO employee VALUES ('E005', '정다은', 'AI', '사원', 3800);

-- ② 특정 컬럼만(나머지는 DEFAULT/NULL)
INSERT INTO employee (emp_id, emp_name) VALUES ('E006', '최민서');

-- ③ SELECT 결과를 삽입
INSERT INTO employee_backup SELECT * FROM employee WHERE hire_date < '2020-01-01';

🔑 암기 ① 전체 컬럼은 컬럼명 생략 가능(VALUES만) ② 특정 컬럼은 (컬럼…) VALUES (값…)INSERT … SELECT로 다른 테이블 데이터 복사. NOT NULL 컬럼은 반드시 값 제공.

⚠️ 함정 PRIMARY KEY 중복 값 삽입 ❌(개체 무결성 위반) / 컬럼 목록과 VALUES 개수·타입 불일치 ❌.

🎯 빈출 INSERT 3형태 문법·NOT NULL/PK 제약 위반. 보통.

UPDATE — 데이터 수정 ·UPDATE·1순위·

[정의] 기존 행의 값을 변경하는 명령어. SET으로 바꿀 컬럼을, WHERE로 대상 행을 지정한다.

SQL
UPDATE employee SET salary = 5000 WHERE emp_id = 'E001';
UPDATE employee SET position = '과장', salary = 6000 WHERE emp_id = 'E002';  -- 다중 컬럼
UPDATE employee SET salary = salary * 1.1;  -- WHERE 없음 → 전체 행 인상

🔑 암기 UPDATE 테이블 SET 컬럼=값 [WHERE 조건]. WHERE를 생략하면 모든 행이 수정된다 — 서브쿼리·CASE 식도 SET 값으로 쓸 수 있다.

⚠️ 함정 WHERE 없는 UPDATE = 전체 행 변경(SET salary = 0 → 모든 직원 연봉 0). 실무·시험 모두 단골 경고 포인트.

🎯 빈출 WHERE 유무에 따른 영향 범위·SET 다중 컬럼 문법. 보통.

DELETE — 데이터 삭제 (DELETE vs TRUNCATE) ·DELETE·1순위·

[정의] 테이블에서 행을 삭제하는 DML. WHERE로 특정 행만, 생략 시 전체 행을 지운다(구조는 남음).

SQL
DELETE FROM employee WHERE emp_id = 'E001';   -- 조건부 삭제
DELETE FROM employee;                          -- 전체 행 삭제(구조 유지)

[표] DELETE vs TRUNCATE — 26강 회수.

구분 DELETE TRUNCATE
분류 DML DDL
WHERE 가능 불가
ROLLBACK 가능 불가(자동 COMMIT)
속도 느림(행마다 로그) 빠름

🔑 암기 DELETE만 DML → ROLLBACK ✅·WHERE ✅. TRUNCATE는 DDL이라 조건도 못 걸고 되돌릴 수도 없다(가장 빠름). 구조까지 지우려면 DROP(26강).

⚠️ 함정 "DELETE는 DDL" ❌(→ DML·★1순위) / "TRUNCATE는 ROLLBACK 가능" ❌(→ DDL이라 불가) / WHERE 없는 DELETE는 전체 삭제(TRUNCATE와 결과는 같지만 느리고 ROLLBACK 가능).

🎯 빈출 DELETE/TRUNCATE/DROP 자리 바꿔치기·DELETE의 DML/ROLLBACK 특성. 거의 매회.


JOIN과 관계대수 연결

JOIN 종류와 결과 행 수 ·JOIN·최고 빈출·

[정의] JOIN은 둘 이상의 테이블을 공통 컬럼으로 연결해 하나의 결과로 조회한다. 결과 행 수 계산이 3과목 최대 킬러 — 어떤 JOIN이냐에 따라 행 수가 달라진다.

[표] 3대 JOIN.

종류 결과 핵심
INNER JOIN 양쪽에 공통으로 매칭되는 행만 매칭 안 되면 탈락
LEFT (OUTER) JOIN 왼쪽 테이블 전부 + 오른쪽 매칭(없으면 NULL) 왼쪽은 모두 살아남음
RIGHT (OUTER) JOIN 오른쪽 테이블 전부 + 왼쪽 매칭(없으면 NULL) 오른쪽은 모두 살아남음

[흐름] 예제 — 직원(3행, 박지호는 부서 NULL) · 부서(3행, 데이터팀은 직원 없음). ON e.dept_code = d.dept_code로 조인.

텍스트
 직원                     부서
 김민준 · D01             D01 · 백엔드팀
 이서연 · D02             D02 · AI팀
 박지호 · (NULL)          D03 · 데이터팀(직원 없음)

 INNER JOIN   2행   김민준-백엔드팀, 이서연-AI팀        (NULL·데이터팀 탈락)
 LEFT  JOIN   3행   + 박지호-NULL                       (직원 전부 살아남음)
 RIGHT JOIN   3행   + NULL-데이터팀                     (부서 전부 살아남음)

🔑 암기 INNER = 교집합(매칭만) / LEFT = 왼쪽 전부 / RIGHT = 오른쪽 전부. 행 수는 INNER(매칭 수) ≤ OUTER(전부 + 매칭). FROM A, B WHERE A.x=B.x는 INNER JOIN과 같다.

⚠️ 함정 매칭 안 되는 행(부서 NULL·직원 없는 부서)의 처리 — INNER는 버리고, OUTER는 NULL로 채워 살린다. 한 부서에 직원이 여럿이면 그 수만큼 행이 늘어난다(행 수 계산 시 매칭 개수 주의).

🎯 빈출 두 테이블을 주고 JOIN 결과 행 수·NULL 포함 여부를 묻는 킬러. INNER/LEFT/RIGHT 행 수 차이가 핵심. 거의 매회.

💡 보충 24강 student ⋈ enrollment ⋈ course 다중 조인이 그대로 SQL 3-테이블 JOIN으로 이어진다 — 연결 테이블(enrollment)을 가운데 두고 양쪽 FK로 묶는다.

SPJD ↔ SQL 매핑 — 25강 관계대수의 SQL 변신 ·관계대수↔SQL·1순위·

[정의] 25강 순수 관계 연산자 SPJD(셀프조디) 가 27강 SQL로 본격 변신하는 종합 무대. 시험은 "σ에 대응하는 SQL 절은?" 식으로 매핑을 직접 묻는다.

[표] SPJD ↔ SQL.

관계대수 기호 SQL
렉트(Select) σ WHERE
로젝트(Project) π SELECT 절(정확히는 SELECT DISTINCT)
인(Join) JOIN … ON(또는 FROM A,B WHERE A.x=B.x)
비전(Division) ÷ GROUP BY … HAVING COUNT ("모든" 조건)

🔑 암기 셀(σ)·프(π)·조(⋈)·디(÷) = WHERE·SELECT·JOIN·HAVING COUNT. σ=행 거르기는 WHERE, π=열 뽑기는 SELECT절, ÷="모든"은 HAVING COUNT로 구현된다.

⚠️ 함정 단어 SELECT가 같다고 σ↔SELECT절로 매칭하면 함정 — σ는 WHERE, SELECT절은 π다. "÷ ↔ ORDER BY" ❌(→ HAVING COUNT) / "π ↔ FROM" ❌(→ SELECT절).

🎯 빈출 관계대수 연산자 ↔ SQL 절 대응. 거의 매회(25강과 교차).


기출 다지기

[기출 1 출제] SQL SELECT 문의 각 절이 처리(실행)되는 순서로 옳은 것은?

  • ① SELECT → FROM → WHERE → GROUP BY → HAVING → ORDER BY
  • ② FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY
  • ③ FROM → SELECT → WHERE → GROUP BY → HAVING → ORDER BY
  • ④ WHERE → FROM → GROUP BY → SELECT → HAVING → ORDER BY
정답 및 해설 보기

정답 ②

처리 순서 = 프위그해셀오 = FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY.

선지 판정
SELECT가 먼저 → ❌(SELECT는 5번째)
프위그해셀오정답
SELECT가 WHERE 앞 → ❌
WHERE가 FROM 앞 → ❌(FROM이 항상 1번째)

🔑 가장 자주 틀리는 함정 = "SELECT가 맨 먼저 처리된다"는 착각. 실제로는 5번째.

[기출 2 출제] 다음 SQL 문에서 문법적 오류가 있는 절은?

SQL
SELECT dept_code, COUNT(*) AS cnt   -- (1)
FROM employee                        -- (2)
WHERE COUNT(*) >= 3                  -- (3)
GROUP BY dept_code;                  -- (4)
  • ① (1)
  • ② (2)
  • ③ (3)
  • ④ (4)
정답 및 해설 보기

정답 ③ (3)

WHERE 절에는 집계 함수를 쓸 수 없다. COUNT(*) 같은 집계 조건은 반드시 HAVING에.

판정
(1) SELECT 정상
(2) FROM 정상
(3) WHERE COUNT(*) 정답(오류) — 집계 함수는 WHERE 불가
(4) GROUP BY 정상

🔑 올바른 형태 = … GROUP BY dept_code HAVING COUNT(*) >= 3. 집계 조건은 HAVING.

[기출 3 출제] 다음 SQL의 실행 결과로 옳은 것은?

텍스트
[employee 테이블]
emp_id | emp_name | bonus
E001   | 김민준    | 500
E002   | 이서연    | NULL
E003   | 박지호    | 300
E004   | 최예린    | NULL
SQL
SELECT COUNT(*), COUNT(bonus) FROM employee;
  • ① 4, 4
  • ② 4, 2
  • ③ 2, 2
  • ④ 2, 4
정답 및 해설 보기

정답 ② (4, 2)

  • COUNT(*) = 전체 행 수 = 4(NULL 포함)
  • COUNT(bonus) = bonus가 NULL 아닌 값의 수 = 2(E001·E003만)

🔑 COUNT(*) → NULL 포함(전체 행) / COUNT(컬럼) → NULL 제외(값 있는 행만). 이 차이가 핵심.

[기출 4 출제] 다음 SQL의 의미로 옳은 것은?

SQL
SELECT * FROM employee WHERE emp_name LIKE '김_준';
  • ① 이름이 '김준'인 직원
  • ② 이름이 '김'으로 시작하고 '준'으로 끝나는 3글자 이름의 직원
  • ③ 이름에 '김'과 '준'이 포함된 직원
  • ④ 이름이 '김준'을 포함하는 직원
정답 및 해설 보기

정답 ②

_정확히 1글자의 임의 문자. '김_준' = 김 + 임의 1글자 + 준 = 정확히 3글자.

기호 의미
% 0개 이상 임의 문자
_ 정확히 1개 임의 문자

🔑 김민준·김서준·김하준 등이 해당. _%(0개 이상)와 혼동하면 함정.

[기출 5 출제] DML(Data Manipulation Language) 명령어가 아닌 것은?

  • ① INSERT
  • ② UPDATE
  • ③ ALTER
  • ④ DELETE
정답 및 해설 보기

정답 ③ ALTER

DML = SELECT · INSERT · UPDATE · DELETE(SIUD).

선지 분류 판정
① INSERT DML 맞음
② UPDATE DML 맞음
ALTER DDL(구조 변경) 정답
④ DELETE DML 맞음

🔑 ALTER·TRUNCATE·DROP·CREATE는 DDL. DML에 섞인 DDL 한 개를 골라내는 단골 함정.

[기출 6 출제] 다음 SQL의 실행 결과로 옳은 것은?

텍스트
[score 테이블]
student_id | subject | score
S001       | 수학     | 90
S001       | 영어     | 80
S002       | 수학     | 70
S002       | 영어     | 85
S003       | 수학     | 95
SQL
SELECT subject, AVG(score) AS 평균점수
FROM score
GROUP BY subject
HAVING AVG(score) >= 82
ORDER BY 평균점수 DESC;
  • ① 수학 85, 영어 82.5
  • ② 영어 82.5, 수학 85
  • ③ 수학 85
  • ④ 영어 82.5
정답 및 해설 보기

정답 ①

프위그해셀오 순서로 추적.

단계 처리
FROM·WHERE score 5행 로드(WHERE 없음)
GROUP BY 수학(90·70·95) / 영어(80·85)
HAVING 수학 평균 (90+70+95)/3 = 85 ✅ / 영어 (80+85)/2 = 82.5 ✅ — 둘 다 82 이상 통과
SELECT·ORDER BY 평균점수 DESC → 수학 85, 영어 82.5

🔑 두 그룹 모두 HAVING 통과 후 내림차순 정렬 → 수학(85)이 영어(82.5)보다 앞.

[기출 7 출제] 다음 두 테이블을 INNER JOIN했을 때 결과 행의 수는? (조인 조건: 사원.부서코드 = 부서.부서코드)

텍스트
[사원]                        [부서]
이준호 · D01                  D01 · 개발팀
김서연 · D01                  D02 · 기획팀
박도윤 · D02                  D03 · 디자인팀
최유나 · (NULL)
정시우 · D04
  • ① 2
  • ② 3
  • ③ 4
  • ④ 5
정답 및 해설 보기

정답 ② 3

INNER JOIN = 양쪽에 매칭되는 행만.

사원 부서코드 매칭 결과
이준호 D01 ✅ 개발팀 포함
김서연 D01 ✅ 개발팀 포함
박도윤 D02 ✅ 기획팀 포함
최유나 NULL 탈락
정시우 D04 ❌(부서에 D04 없음) 탈락

→ D01 매칭 2행 + D02 매칭 1행 = 3행. D03(디자인팀)은 직원이 없어 INNER 결과에 없음.

🔑 INNER는 매칭만 — NULL·매칭 실패 행은 탈락. 한 부서에 직원이 여럿이면 그 수만큼 행이 늘어난다(D01이 2행). LEFT JOIN이었다면 최유나·정시우도 NULL로 살아 5행.

[기출 8 출제] 관계대수의 순수 관계 연산자와 대응하는 SQL 구성으로 옳지 않은 것은? (부정형)

  • ① Select(σ) ↔ WHERE 절
  • ② Project(π) ↔ SELECT 절
  • ③ Join(⋈) ↔ JOIN … ON
  • ④ Division(÷) ↔ ORDER BY 절
정답 및 해설 보기

정답 ④

Division(÷, "모든" 조건)은 GROUP BY … HAVING COUNT로 구현한다 — ORDER BY(정렬)와 무관.

선지 판정
① σ ↔ WHERE 옳음(행 거르기)
② π ↔ SELECT 옳음(열 뽑기·DISTINCT)
③ ⋈ ↔ JOIN ON 옳음
÷ ↔ ORDER BY 정답(틀림) — ÷는 HAVING COUNT

🔑 셀(σ)·프(π)·조(⋈)·디(÷) = WHERE·SELECT·JOIN·HAVING COUNT. 단어 SELECT가 같다고 σ↔SELECT절로 매칭하면 함정(σ는 WHERE, SELECT절은 π).


한 장 요약

영역 핵심 암기팁
DML 4종 SELECT·INSERT·UPDATE·DELETE · ROLLBACK ✅ SIUD(셀·인·업·델)
처리 순서 FROM·WHERE·GROUP BY·HAVING·SELECT·ORDER BY 프위그해셀오(SELECT는 5번째)
WHERE 연산자 비교·논리·BETWEEN·IN·LIKE %=0개+·_=정확히 1글자
NULL 처리 비교는 IS NULL·산술은 결과 NULL = NULL
GROUP BY 그룹화 컬럼·집계 함수만 SELECT 가능 일반 컬럼 SELECT ❌
집계 함수 COUNT·SUM·AVG·MAX·MIN COUNT(*)만 NULL 포함·나머지 제외
WHERE vs HAVING 행 조건=WHERE / 집계 조건=HAVING 집계 함수 보이면 무조건 HAVING
서브쿼리 단일행== / 다중행=IN·EXISTS 다중행에 =
INSERT/UPDATE/DELETE INSERT 3형태 · WHERE 없는 U/D=전체 DELETE만 DML·ROLLBACK✅
JOIN INNER(매칭)·LEFT(왼쪽 전부)·RIGHT(오른쪽 전부) 행 수 = 매칭 개수 주의
SPJD↔SQL σ·π·⋈·÷ = WHERE·SELECT·JOIN·HAVING COUNT SELECT절=π(σ 아님)

🎯 합격 한 끗: 27강은 세 무기면 출제분의 80%가 즉답이다 — ① 프위그해셀오(처리 순서, 매 회차) ② 집계 함수 조건은 무조건 HAVING(COUNT/SUM/AVG/MAX/MIN) ③ JOIN 결과 행 수(INNER=매칭만·OUTER=한쪽 전부+NULL). 여기에 COUNT(*) NULL 포함·LIKE '_' 한 글자·DELETE만 DML(ROLLBACK✅)·SPJD↔SQL 매핑(σ=WHERE·SELECT절=π)만 더 얹으면 끝.

전체 목록 필기 이론

합격까지

정처기, 혼자 막막하다면

초개인화 학습앱 Klue와 에듀윌 온라인강의로 합격까지 이어가세요.