← 강의 목록

SQLD

5편 - SQLD 2과목 1장 : SQL 기본

SQLD 과목2: SQL 기본 및 활용


제1장. SQL 기본


1.1 관계형 데이터베이스 개요

1.1.1 데이터베이스와 관계형 데이터베이스

관계형 데이터베이스(RDBMS)는 데이터를 2차원 테이블 구조로 저장하며, 테이블 간의 관계(Relationship)를 통해 데이터를 관리한다.

1.1.2 SQL (Structured Query Language)

SQL은 관계형 데이터베이스를 조작하기 위한 표준 언어이다.

SQL 분류설명주요 명령어
DDL (Data Definition Language)데이터 구조 정의CREATE, ALTER, DROP, RENAME, TRUNCATE
DML (Data Manipulation Language)데이터 조작SELECT, INSERT, UPDATE, DELETE
DCL (Data Control Language)권한 제어GRANT, REVOKE
TCL (Transaction Control Language)트랜잭션 제어COMMIT, ROLLBACK, SAVEPOINT

시험 핵심: DDL은 AUTO COMMIT이 발생한다 (Oracle 기준). DML은 명시적 COMMIT이 필요하다.

1.1.3 테이블 용어 정리

용어다른 표현설명
테이블 (Table)릴레이션, 엔터티데이터를 저장하는 2차원 구조
행 (Row)튜플, 레코드, 인스턴스하나의 데이터 단위
열 (Column)필드, 속성, 칼럼데이터의 항목
기본키 (PK)Primary Key행을 유일하게 식별하는 칼럼
외래키 (FK)Foreign Key다른 테이블의 PK를 참조하는 칼럼

1.2 DDL (Data Definition Language)

1.2.1 CREATE TABLE

CREATE TABLE 사원 (
    사원번호  NUMBER(10)    NOT NULL,
    사원명    VARCHAR2(50)  NOT NULL,
    입사일    DATE          DEFAULT SYSDATE,
    급여      NUMBER(10,2),
    부서코드  VARCHAR2(10),
    CONSTRAINT PK_사원 PRIMARY KEY (사원번호),
    CONSTRAINT FK_사원_부서 FOREIGN KEY (부서코드) REFERENCES 부서(부서코드)
);

주요 데이터 타입 (Oracle)

타입설명예시
CHAR(n)고정 길이 문자열 (남는 공간은 공백 패딩)CHAR(10) → 'ABC '
VARCHAR2(n)가변 길이 문자열VARCHAR2(10) → 'ABC'
NUMBER(p,s)숫자 (전체자릿수, 소수점자릿수)NUMBER(10,2)
DATE날짜와 시간SYSDATE
CLOB대용량 문자 데이터4GB까지

시험 핵심: CHAR vs VARCHAR2

  • CHAR: 고정 길이. 비교 시 공백을 채워서 비교한다.
  • VARCHAR2: 가변 길이. 실제 저장된 값만으로 비교한다.
  • CHAR('AA') = CHAR('AA ') → TRUE (공백 패딩 비교)
  • VARCHAR2('AA') = VARCHAR2('AA ') → FALSE (공백도 문자로 인식)

1.2.2 제약조건 (Constraint)

제약조건설명
PRIMARY KEY유일성 + NOT NULL. 테이블당 1개만 가능
UNIQUE유일성 보장. NULL 허용 (Oracle에서 NULL은 여러 개 가능)
NOT NULLNULL 값 불허
CHECK특정 조건을 만족하는 값만 허용
FOREIGN KEY참조 무결성 보장
-- CHECK 제약조건 예시
CREATE TABLE 사원 (
    사원번호 NUMBER PRIMARY KEY,
    급여     NUMBER CHECK (급여 > 0),
    성별     CHAR(1) CHECK (성별 IN ('M', 'F'))
);

FK 삭제 옵션

옵션동작
CASCADE부모 삭제 시 자식도 함께 삭제
SET NULL부모 삭제 시 자식의 FK를 NULL로 설정
SET DEFAULT부모 삭제 시 자식의 FK를 기본값으로 설정
RESTRICT자식이 있으면 부모 삭제 불가
NO ACTIONRESTRICT와 유사 (트랜잭션 종료 시 체크)

1.2.3 ALTER TABLE

-- 칼럼 추가
ALTER TABLE 사원 ADD (이메일 VARCHAR2(100));

-- 칼럼 수정
ALTER TABLE 사원 MODIFY (사원명 VARCHAR2(100));

-- 칼럼 삭제
ALTER TABLE 사원 DROP COLUMN 이메일;

-- 칼럼명 변경
ALTER TABLE 사원 RENAME COLUMN 급여 TO 월급;

-- 제약조건 추가
ALTER TABLE 사원 ADD CONSTRAINT CK_사원_급여 CHECK (급여 >= 0);

-- 제약조건 삭제
ALTER TABLE 사원 DROP CONSTRAINT CK_사원_급여;

1.2.4 DROP TABLE & TRUNCATE TABLE

-- 테이블 삭제 (구조 + 데이터 모두 삭제)
DROP TABLE 사원;
DROP TABLE 사원 CASCADE CONSTRAINTS;  -- FK 제약조건도 함께 삭제

-- 테이블 데이터만 삭제 (구조는 유지, 복구 불가)
TRUNCATE TABLE 사원;

DROP vs TRUNCATE vs DELETE 비교

구분DROPTRUNCATEDELETE
분류DDLDDL (일부 DML 특성)DML
테이블 구조삭제됨유지됨유지됨
저장 공간반환반환유지 (반환 안 됨)
ROLLBACK불가불가가능 (COMMIT 전)
로그기록 안 됨기록 안 됨기록됨
WHERE 절사용 불가사용 불가사용 가능
AUTO COMMITOOX

1.3 DML (Data Manipulation Language)

1.3.1 INSERT

-- 전체 칼럼 입력
INSERT INTO 사원 VALUES (1001, '홍길동', SYSDATE, 5000000, 'D01');

-- 특정 칼럼만 입력
INSERT INTO 사원 (사원번호, 사원명, 부서코드) VALUES (1002, '김철수', 'D02');

-- 다른 테이블로부터 입력
INSERT INTO 사원_백업 SELECT * FROM 사원 WHERE 부서코드 = 'D01';

1.3.2 UPDATE

UPDATE 사원
SET    급여 = 급여 * 1.1,
       부서코드 = 'D03'
WHERE  사원번호 = 1001;

주의: WHERE 절을 생략하면 테이블의 모든 행이 수정된다!

1.3.3 DELETE

DELETE FROM 사원 WHERE 사원번호 = 1001;

-- 전체 삭제 (ROLLBACK 가능)
DELETE FROM 사원;

1.3.4 MERGE (Oracle)

MERGE INTO 사원_대상 T
USING 사원_원본 S
ON (T.사원번호 = S.사원번호)
WHEN MATCHED THEN
    UPDATE SET T.급여 = S.급여
WHEN NOT MATCHED THEN
    INSERT (사원번호, 사원명, 급여) VALUES (S.사원번호, S.사원명, S.급여);

1.4 SELECT 문

1.4.1 기본 SELECT

SELECT 사원번호, 사원명, 급여
FROM   사원
WHERE  부서코드 = 'D01'
ORDER BY 급여 DESC;

SQL 실행 순서 (매우 중요!)

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

시험 핵심: SELECT에서 정의한 별칭(Alias)은 ORDER BY에서만 사용 가능하다. WHERE, GROUP BY, HAVING에서는 사용 불가하다.

1.4.2 별칭 (Alias)

-- 칼럼 별칭
SELECT 사원명 AS 이름, 급여 * 12 AS 연봉
FROM   사원;

-- 테이블 별칭
SELECT e.사원명, d.부서명
FROM   사원 e, 부서 d
WHERE  e.부서코드 = d.부서코드;

1.4.3 산술 연산자

-- NULL과의 연산 결과는 항상 NULL
SELECT 사원명, 급여, 급여 + 보너스 AS 총급여
FROM   사원;
-- 만약 보너스가 NULL이면 총급여도 NULL!

-- NVL 함수로 해결
SELECT 사원명, 급여, 급여 + NVL(보너스, 0) AS 총급여
FROM   사원;

1.4.4 DISTINCT

-- 중복 제거
SELECT DISTINCT 부서코드 FROM 사원;

-- 여러 칼럼에 DISTINCT → 칼럼 조합이 유일한 행만 반환
SELECT DISTINCT 부서코드, 직급 FROM 사원;

1.5 WHERE 절

1.5.1 비교 연산자

연산자설명예시
=같다급여 = 5000
>, <, >=, <=크다/작다급여 >= 3000
<>, !=, ^=같지 않다부서코드 <> 'D01'

1.5.2 SQL 연산자

연산자설명예시
BETWEEN a AND ba 이상 b 이하급여 BETWEEN 3000 AND 5000
IN (list)목록 중 하나라도 일치부서코드 IN ('D01', 'D02', 'D03')
LIKE패턴 매칭사원명 LIKE '김%'
IS NULLNULL 확인보너스 IS NULL

LIKE 와일드카드

와일드카드설명예시
%0개 이상의 임의 문자'김%' → 김으로 시작하는 모든 값
_정확히 1개의 임의 문자'김__' → 김 + 정확히 2글자
-- ESCAPE 사용 (%, _ 를 실제 문자로 검색할 때)
SELECT * FROM 상품 WHERE 상품명 LIKE '%20\%%' ESCAPE '\';
-- '20%'를 포함하는 상품명 검색

1.5.3 논리 연산자

우선순위연산자
1 (높음)NOT
2AND
3 (낮음)OR
-- AND가 OR보다 먼저 실행됨!
SELECT * FROM 사원
WHERE 부서코드 = 'D01' OR 부서코드 = 'D02' AND 급여 >= 5000;
-- 실제 실행: 부서코드='D01' OR (부서코드='D02' AND 급여>=5000)

-- 의도한 대로 하려면 괄호 사용
SELECT * FROM 사원
WHERE (부서코드 = 'D01' OR 부서코드 = 'D02') AND 급여 >= 5000;

1.5.4 NULL의 특성

- NULL은 '알 수 없는 값(Unknown)'이다
- NULL과의 모든 비교 연산 결과는 Unknown(FALSE 처리)이다
- NULL과의 모든 산술 연산 결과는 NULL이다
- NULL = NULL → Unknown (FALSE)
- NULL <> NULL → Unknown (FALSE)
- NULL IS NULL → TRUE (IS NULL/IS NOT NULL로만 비교)

3치 논리 (Three-Valued Logic)

ANDTRUEFALSEUNKNOWN
TRUETRUEFALSEUNKNOWN
FALSEFALSEFALSEFALSE
UNKNOWNUNKNOWNFALSEUNKNOWN
ORTRUEFALSEUNKNOWN
TRUETRUETRUETRUE
FALSETRUEFALSEUNKNOWN
UNKNOWNTRUEUNKNOWNUNKNOWN
NOT결과
TRUEFALSE
FALSETRUE
UNKNOWNUNKNOWN

시험 핵심: NOT IN 사용 시 서브쿼리 결과에 NULL이 포함되면 결과가 공집합이 된다!

-- 위험한 예시
SELECT * FROM 사원
WHERE 부서코드 NOT IN (SELECT 부서코드 FROM 부서 WHERE 부서코드 IS NOT NULL);
-- 서브쿼리에 NULL이 있다면 결과 0건

1.6 함수 (Function)

1.6.1 문자열 함수

함수설명Oracle 예시결과
UPPER(s)대문자 변환UPPER('hello')'HELLO'
LOWER(s)소문자 변환LOWER('HELLO')'hello'
INITCAP(s)첫 글자만 대문자INITCAP('hello world')'Hello World'
LENGTH(s)문자열 길이LENGTH('ABC')3
SUBSTR(s,m,n)부분 문자열SUBSTR('ABCDEF',2,3)'BCD'
INSTR(s1,s2)문자열 위치INSTR('ABCABC','B')2
LPAD(s,n,c)왼쪽 패딩LPAD('123',5,'0')'00123'
RPAD(s,n,c)오른쪽 패딩RPAD('123',5,'0')'12300'
LTRIM(s,c)왼쪽 제거LTRIM(' ABC')'ABC'
RTRIM(s,c)오른쪽 제거RTRIM('ABC ')'ABC'
TRIM(s)양쪽 공백 제거TRIM(' ABC ')'ABC'
REPLACE(s,a,b)문자 치환REPLACE('ABCABC','B','X')'AXCAXC'
CONCAT(s1,s2)문자 결합CONCAT('AB','CD')'ABCD'
||문자 결합 (Oracle)'AB' || 'CD''ABCD'

1.6.2 숫자 함수

함수설명예시결과
ROUND(n,m)반올림ROUND(15.567, 1)15.6
TRUNC(n,m)버림TRUNC(15.567, 1)15.5
CEIL(n)올림 (정수)CEIL(15.1)16
FLOOR(n)내림 (정수)FLOOR(15.9)15
MOD(n,m)나머지MOD(10, 3)1
ABS(n)절대값ABS(-15)15
SIGN(n)부호 (양수1, 0, 음수-1)SIGN(-15)-1
POWER(n,m)거듭제곱POWER(2,3)8

1.6.3 날짜 함수 (Oracle)

함수설명예시
SYSDATE현재 날짜/시간SYSDATE
ADD_MONTHS(d,n)n개월 후 날짜ADD_MONTHS(SYSDATE, 3)
MONTHS_BETWEEN(d1,d2)두 날짜 간 개월 수MONTHS_BETWEEN('2024-06-01','2024-01-01') → 5
LAST_DAY(d)해당 월의 마지막 날LAST_DAY('2024-02-01') → 2024-02-29
NEXT_DAY(d, day)다음 특정 요일NEXT_DAY(SYSDATE, '월요일')
TRUNC(d, fmt)날짜 절삭TRUNC(SYSDATE, 'MM') → 해당 월 1일
ROUND(d, fmt)날짜 반올림ROUND(SYSDATE, 'YYYY')
-- 날짜 연산
SELECT SYSDATE + 7 FROM DUAL;         -- 7일 후
SELECT SYSDATE - 7 FROM DUAL;         -- 7일 전
SELECT SYSDATE + 1/24 FROM DUAL;      -- 1시간 후
SELECT 날짜1 - 날짜2 FROM DUAL;        -- 날짜 간 일수 차이 (숫자 반환)
-- 날짜 + 숫자 = 날짜
-- 날짜 - 날짜 = 숫자 (일수)
-- 날짜 + 날짜 = 에러!

1.6.4 변환 함수

(1) 명시적 형변환 vs 암시적 형변환

문자 ←→ 숫자: TO_CHAR / TO_NUMBER
문자 ←→ 날짜: TO_CHAR / TO_DATE

시험 핵심: 암시적 형변환은 성능 저하의 원인이 될 수 있다. 인덱스 칼럼에 암시적 형변환이 발생하면 인덱스를 사용하지 못할 수 있다.

-- TO_CHAR: 숫자/날짜 → 문자
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') FROM DUAL;
-- '2024-05-15 14:30:00'

SELECT TO_CHAR(1234567, '9,999,999') FROM DUAL;
-- '1,234,567'

-- TO_DATE: 문자 → 날짜
SELECT TO_DATE('2024-05-15', 'YYYY-MM-DD') FROM DUAL;

-- TO_NUMBER: 문자 → 숫자
SELECT TO_NUMBER('1,234', '9,999') FROM DUAL;
-- 1234

날짜 포맷 모델

포맷설명예시
YYYY4자리 연도2024
MM2자리 월05
DD2자리 일15
HH2424시간 형식 시14
MI30
SS00
DAY요일 (전체)수요일
DY요일 (약어)

1.6.5 NULL 관련 함수

함수설명예시결과
NVL(a, b)a가 NULL이면 b 반환NVL(보너스, 0)보너스가 NULL이면 0
NVL2(a, b, c)a가 NULL이 아니면 b, NULL이면 cNVL2(보너스, '있음', '없음')
NULLIF(a, b)a=b이면 NULL, 아니면 a 반환NULLIF(10, 10)NULL
COALESCE(a,b,c..)인자 중 첫 번째 NULL이 아닌 값COALESCE(NULL, NULL, 3)3
-- COALESCE는 NVL의 확장판
SELECT COALESCE(보너스, 성과급, 수당, 0) AS 추가급여
FROM   사원;
-- 보너스 → 성과급 → 수당 순서로 NULL이 아닌 첫 번째 값 반환

1.6.6 CASE 표현식

-- Simple CASE
SELECT 사원명,
       CASE 직급
           WHEN '부장' THEN 급여 * 1.3
           WHEN '과장' THEN 급여 * 1.2
           WHEN '대리' THEN 급여 * 1.1
           ELSE 급여
       END AS 인상급여
FROM   사원;

-- Searched CASE (더 유연)
SELECT 사원명,
       CASE
           WHEN 급여 >= 8000 THEN '고액'
           WHEN 급여 >= 5000 THEN '중간'
           WHEN 급여 >= 3000 THEN '보통'
           ELSE '저액'
       END AS 급여등급
FROM   사원;

DECODE 함수 (Oracle 전용)

-- CASE의 간편 버전 (등호 비교만 가능)
SELECT 사원명,
       DECODE(직급, '부장', 급여*1.3,
                    '과장', 급여*1.2,
                    '대리', 급여*1.1,
                    급여) AS 인상급여
FROM   사원;

1.7 ORDER BY 절

1.7.1 정렬 기본

-- 오름차순 (기본값)
SELECT * FROM 사원 ORDER BY 급여 ASC;

-- 내림차순
SELECT * FROM 사원 ORDER BY 급여 DESC;

-- 다중 정렬
SELECT * FROM 사원 ORDER BY 부서코드 ASC, 급여 DESC;

-- 칼럼 번호로 정렬
SELECT 사원명, 급여, 부서코드 FROM 사원 ORDER BY 3, 2 DESC;
-- 3번째 칼럼(부서코드) 오름차순, 2번째 칼럼(급여) 내림차순

1.7.2 NULL과 정렬

Oracle에서 NULL은 가장 큰 값으로 취급된다.

-- Oracle: NULL이 마지막에 위치 (ASC)
SELECT * FROM 사원 ORDER BY 보너스 ASC;
-- 100, 200, 300, NULL, NULL

-- NULL을 제어하려면
SELECT * FROM 사원 ORDER BY 보너스 ASC NULLS FIRST;
-- NULL, NULL, 100, 200, 300

SELECT * FROM 사원 ORDER BY 보너스 DESC NULLS LAST;
-- 300, 200, 100, NULL, NULL

연습문제


기본 문제

문제 1. 다음 SQL의 결과로 올바른 것은?

SELECT NVL(NULL, 'A') || NVL('B', 'C') || NVL(NULL, NULL) FROM DUAL;

① ABC ② AB ③ ABNull ④ AB (NULL)

정답: ② 해설: NVL(NULL,'A')='A', NVL('B','C')='B', NVL(NULL,NULL)=NULL. 문자열과 NULL을 ||로 연결하면 NULL이 무시되어 'AB'가 된다. (Oracle에서 NULL || 'A' = 'A')


문제 2. 다음 중 TRUNCATE에 대한 설명으로 올바르지 않은 것은?

① DDL이므로 AUTO COMMIT이 발생한다 ② 테이블 구조는 유지된다 ③ WHERE 조건을 사용할 수 있다 ④ ROLLBACK이 불가능하다

정답: ③ 해설: TRUNCATE는 WHERE 절을 사용할 수 없다. 테이블의 전체 데이터를 삭제한다.


문제 3. 다음 SQL의 실행 순서로 올바른 것은?

SELECT 부서코드, COUNT(*) AS 인원
FROM 사원
WHERE 급여 >= 3000
GROUP BY 부서코드
HAVING COUNT(*) >= 3
ORDER BY 인원 DESC;

① SELECT → FROM → WHERE → GROUP BY → HAVING → ORDER BY ② FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY ③ FROM → GROUP BY → WHERE → HAVING → SELECT → ORDER BY ④ FROM → WHERE → HAVING → GROUP BY → SELECT → ORDER BY

정답: ② 해설: SQL 실행 순서는 FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY이다.


문제 4. 다음 테이블에서 SQL의 결과는?

사원 테이블:

사원번호급여보너스
100150001000
10023000NULL
10034000NULL
100460002000
SELECT COUNT(*), COUNT(보너스), AVG(보너스) FROM 사원;

① 4, 4, 750 ② 4, 2, 1500 ③ 4, 2, 750 ④ 2, 2, 1500

정답: ② 해설: COUNT(*)=4(전체행), COUNT(보너스)=2(NULL제외), AVG(보너스)=(1000+2000)/2=1500 (NULL 제외하고 계산)


문제 5. RANK, DENSE_RANK, ROW_NUMBER의 차이를 묻는 문제:

급여 데이터: 5000, 5000, 4000, 3000

DENSE_RANK() OVER (ORDER BY 급여 DESC)의 결과로 올바른 것은?

① 1, 1, 3, 4 ② 1, 2, 3, 4 ③ 1, 1, 2, 3 ④ 1, 1, 2, 4

정답: ③ 해설: DENSE_RANK는 동일 순위가 있어도 다음 순위를 건너뛰지 않는다. 5000(1위), 5000(1위), 4000(2위), 3000(3위).


문제 6. 다음 중 LEFT OUTER JOIN의 Oracle 전통 표기법으로 올바른 것은?

-- ANSI 표준:
SELECT e.사원명, d.부서명
FROM 사원 e LEFT OUTER JOIN 부서 d ON e.부서코드 = d.부서코드;

① WHERE e.부서코드(+) = d.부서코드 ② WHERE e.부서코드 = d.부서코드(+) ③ WHERE e.부서코드 = d.부서코드 LEFT(+) ④ WHERE (+)e.부서코드 = d.부서코드

정답: ② 해설: Oracle에서 (+)는 데이터가 없는(부족한) 쪽에 붙인다. LEFT OUTER JOIN은 왼쪽(사원)의 모든 행을 보존하므로, 오른쪽(부서)에 (+)를 붙인다.


문제 7. 다음 SQL의 결과 건수는?

사원 테이블: 10건, 부서 테이블: 5건

SELECT * FROM 사원 CROSS JOIN 부서;

① 10건 ② 15건 ③ 50건 ④ 5건

정답: ③ 해설: CROSS JOIN은 카테시안 곱이므로 10 × 5 = 50건이다.


문제 8. 다음 계층형 쿼리에서 PRIOR 키워드의 위치가 의미하는 것은?

CONNECT BY PRIOR 사원번호 = 관리자번호

① 역방향 전개 (자식→부모) ② 순방향 전개 (부모→자식) ③ 같은 레벨 전개 ④ 전체 전개

정답: ② 해설: PRIOR가 사원번호(PK) 쪽에 있으므로 이전 행의 사원번호가 현재 행의 관리자번호와 같은 행을 찾는다. 이는 부모에서 자식으로 가는 순방향 전개이다.


문제 9. 다음 중 서브쿼리의 종류와 위치가 올바르게 매칭된 것은?

① 스칼라 서브쿼리 - FROM 절 ② 인라인 뷰 - SELECT 절 ③ 연관 서브쿼리 - WHERE 절 ④ 중첩 서브쿼리 - HAVING 절만

정답: ③ 해설: 스칼라 서브쿼리는 SELECT 절, 인라인 뷰는 FROM 절, 연관 서브쿼리는 주로 WHERE 절에서 메인 쿼리의 칼럼을 참조하여 사용된다.


문제 10. 트랜잭션의 특성 중 "트랜잭션이 전부 실행되거나 전부 취소되어야 한다"는 특성은?

① 일관성 (Consistency) ② 원자성 (Atomicity) ③ 고립성 (Isolation) ④ 지속성 (Durability)

정답: ② 해설: 원자성(Atomicity)은 All or Nothing 원칙으로, 트랜잭션의 모든 연산이 완전히 수행되거나 전혀 수행되지 않아야 함을 의미한다.


심화 문제

문제 11. 다음 결과를 예측하시오:

SELECT 1 FROM DUAL WHERE NULL = NULL;

① 1 ② NULL ③ 결과 없음 (0건) ④ 에러

정답: ③ 해설: NULL = NULL은 Unknown이므로 WHERE 조건이 TRUE가 아니어서 결과가 반환되지 않는다. NULL 비교는 IS NULL / IS NOT NULL을 사용해야 한다.


문제 12. 다음 SQL에서 ROLLUP의 결과로 생성되는 소계 행의 수는?

SELECT 부서코드, 직급, 성별, SUM(급여)
FROM 사원
GROUP BY ROLLUP(부서코드, 직급, 성별);

부서코드 3개, 직급 2개, 성별 2개인 경우:

① 3개 ② 6개 ③ 총 그룹 수에 따라 다름 ④ 인자 수 + 1 = 4단계 소계

정답: ④ (개념적) 해설: ROLLUP(A, B, C)는 4단계의 소계를 생성한다: (A, B, C) → (A, B) → (A) → () 전체 총계. 즉, 일반 그룹 + A,B별 소계 + A별 소계 + 전체 총계.


문제 13. 다음 두 SQL의 결과가 같은가 다른가?

-- SQL1
SELECT * FROM 사원 WHERE 부서코드 NOT IN ('D01', 'D02', NULL);

-- SQL2
SELECT * FROM 사원 WHERE 부서코드 NOT IN ('D01', 'D02');

① 같다 ② 다르다 (SQL1이 더 적다) ③ 다르다 (SQL1이 0건) ④ 에러 발생

정답: ③ 해설: NOT IN에 NULL이 포함되면 모든 비교 결과가 Unknown이 되어 결과가 0건이 된다. 이는 NULL의 비교 연산 특성 때문이다. NOT IN (A, B, NULL) → 부서코드<>A AND 부서코드<>B AND 부서코드<>NULL 마지막 조건이 항상 Unknown이므로 전체가 Unknown → 결과 없음.