13단원 'SQL 기본'의 일곱 레슨에서 7문제, 앞 단원(11·12)에서 3문제를 섞었고, 끝에 실기 꼴 3문제가 있습니다. 앞 단원 문제가 어느 레슨인지는 정답을 펼치면 보입니다. 실기 꼴은 종이에 답을 끝까지 쓴 뒤 펼치세요. 띄어쓰기만 다르면 같은 답입니다.
SQL 문제는 아래 네 표로 풉니다. 블록마다 처음 데이터에서 시작합니다. 학생의 학과코드는 학과를, 수강의 학번은 학생을, 수강의 과목코드와 과목의 선수과목은 과목을 가리킵니다. 학생의 학년은 1부터 4까지만 받습니다.
학과
| 학과코드 | 학과명 | 건물 |
|---|---|---|
| CS | 컴퓨터 | 공학관 |
| EE | 전자 | 공학관 |
| BA | 경영 | 경영관 |
학생
| 학번 | 이름 | 학년 | 학과코드 |
|---|---|---|---|
| 101 | 김민수 | 3 | CS |
| 102 | 이서준 | 2 | CS |
| 103 | 김지민 | 2 | CS |
| 104 | 박서연 | 1 | EE |
| 105 | 최민준 | 3 | EE |
| 106 | 정하윤 | 3 | EE |
| 107 | 강도현 | 1 | NULL |
과목
| 과목코드 | 과목명 | 학점 | 선수과목 |
|---|---|---|---|
| DS | 자료구조 | 3 | NULL |
| OS | 운영체제 | 3 | DS |
| NW | 네트워크 | 2 | OS |
수강
| 학번 | 과목코드 | 점수 |
|---|---|---|
| 101 | DS | 85 |
| 101 | OS | 75 |
| 101 | NW | 80 |
| 102 | DS | 70 |
| 102 | OS | 60 |
| 103 | DS | 65 |
| 103 | NW | 55 |
| 104 | OS | 75 |
| 104 | NW | 95 |
| 105 | DS | 100 |
| 105 | NW | 90 |
| 107 | NW | 50 |
문제 1
다음 가운데 같은 종류에 드는 명령어 짝을 고르세요.
- ①
ALTER와UPDATE - ②
DROP과DELETE - ③
GRANT와SELECT - ④
CREATE와DROP
정답
④ — 둘 다 표의 틀을 다루는 DDL입니다. CREATE는 틀을 만들고 DROP은 틀까지 없앱니다.
- ① 둘 다 '바꾼다'는 말에 끌렸습니다.
ALTER는 표의 틀을 바꾸는 DDL,UPDATE는 표 안의 행을 바꾸는 DML입니다. - ② 둘 다 '지운다'는 말에 끌렸습니다.
DROP은 표를 틀까지 없애는 DDL,DELETE는 행만 지우는 DML입니다. - ③
GRANT SELECT ON 학생처럼 한 문장에 함께 나오는 것을 보고 같은 종류로 봤습니다. 권한을 주는GRANT는 DCL, 행을 꺼내 오는SELECT는 DML입니다.
다시 볼 레슨: SQL의 분류
문제 2
과목 표에 담당교수 열을 하나 더하고 표 전체를 조회했습니다. 결과로 알맞은 것을 고르세요.
ALTER TABLE 과목
ADD 담당교수 VARCHAR(20);
SELECT *
FROM 과목
ORDER BY 과목코드;
- ① 열이 다섯이 되고, 이미 있던 세 행의 담당교수는 모두 NULL이다
- ② 열이 다섯이 되고, 담당교수 열이 과목코드 바로 뒤에 끼어든다
- ③ 열이 다섯이 되고, 이미 있던 세 행의 담당교수에 빈 문자열이 들어간다
- ④ 이미 든 행이 있어 열을 더하지 못하고 오류가 난다
정답
① — ALTER TABLE … ADD로 더한 열은 맨 뒤에 붙고, 이미 있던 행의 그 칸은 NULL이 됩니다.
- ② 열의 자리를 고를 수 있다고 봤습니다. 더한 열은 늘 맨 뒤에 붙습니다.
- ③ NULL을 빈 문자열과 같게 봤습니다. 값을 적지 않은 칸은 '아무 값도 없음'인 NULL입니다.
- ④ 값을 채울 수 없으면 막힌다고 봤습니다.
NOT NULL을 걸지 않은 열은 행이 있어도 더할 수 있습니다.
| 과목코드 | 과목명 | 학점 | 선수과목 | 담당교수 |
|---|---|---|---|---|
| DS | 자료구조 | 3 | NULL | NULL |
| NW | 네트워크 | 2 | OS | NULL |
| OS | 운영체제 | 3 | DS | NULL |
다시 볼 레슨: DDL: CREATE·ALTER·DROP
문제 3
학생.학과코드는 학과.학과코드를 참조합니다. 학과 표에서 'EE' 행을 지울 때 EE 학생 행은 남기고 학과코드만 NULL로 바꾸려고 합니다. 무엇을 어디에 정해 두어야 하는지 알맞은 것을 고르세요.
- ① 학생 표의 외래키에
ON DELETE CASCADE - ② 학생 표의 외래키에
ON DELETE SET NULL - ③ 학과 표의 기본키에
ON DELETE CASCADE - ④ 학과 표의 기본키에
ON DELETE SET NULL
정답
② — 참조 동작은 참조하는 쪽(자식) 표의 외래키에 정합니다. 부모 행이 지워질 때 자식 행은 남기고 외래키 값만 NULL로 바꾸는 동작이 SET NULL입니다.
- ①
CASCADE를 '부모가 지워졌다고 자식의 값을 고친다'로 봤습니다.CASCADE는 EE 학생 행(104·105·106)까지 함께 지웁니다. - ③ 동작을 부모 표에 붙인다고 보고,
CASCADE가 값만 고친다고도 봤습니다. 동작은 학생 표의 외래키에 붙이고,CASCADE는 학생 행까지 지웁니다. - ④ 동작을 지워지는 부모 표에 붙인다고 봤습니다. 참조 동작은 외래키를 만들 때
REFERENCES 학과 (학과코드)뒤에 함께 적습니다.
다시 볼 레슨: 무결성 제약 조건
문제 4
학생 표에서 다음 두 조건에 맞는 행 수로 알맞은 것을 고르세요.
-
(1)
WHERE 학과코드 <> 'CS' -
(2)
WHERE 학과코드 <> 'CS' OR 학과코드 IS NULL -
① (1) 3행 · (2) 4행
-
② (1) 3행 · (2) 5행
-
③ (1) 4행 · (2) 4행
-
④ (1) 4행 · (2) 5행
정답
① — (1)은 학과코드가 EE인 104·105·106 세 행입니다. 학과코드가 NULL인 강도현은 NULL과 견준 결과가 참이 되지 않아 빠집니다. (2)는 IS NULL이 그 강도현을 더해 네 행입니다.
- ② (2)에서 강도현을 두 번 셌습니다.
OR로 이어도 한 행은 한 번만 나옵니다. - ③ (1)에 강도현을 넣었습니다. NULL은 'CS가 아니다'도 'CS다'도 되지 않아
<>조건에서 빠집니다. - ④ 두 오해가 겹쳤습니다. (1)에 강도현을 넣고 (2)에서 한 번 더 셌습니다.
다시 볼 레슨: SELECT 기본: 조건과 정렬
문제 5
다음 SQL과 같은 결과를 내는 관계대수 식을 고르세요.
SELECT DISTINCT 학년
FROM 학생
WHERE 학과코드 = 'EE'
ORDER BY 학년;
- ①
σ 학년 (π 학과코드='EE' (학생)) - ②
σ 학과코드='EE' (π 학년 (학생)) - ③
π 학년 (σ 학과코드='EE' (학생)) - ④
π 학과코드='EE' (σ 학년 (학생))
정답
③ — σ는 조건으로 튜플을 고르고 π는 속성을 고릅니다. SQL의 WHERE가 σ, SELECT 열 목록이 π에 해당합니다. 안쪽부터 EE 학생 셋을 고른 뒤 학년만 남겨 1·3 두 튜플이 됩니다. π가 겹치는 3을 하나로 줄이는 것이 DISTINCT와 같은 일입니다.
- ① 두 기호의 자리를 바꿔 썼습니다. σ 뒤에는 조건, π 뒤에는 속성이 옵니다.
- ② 차례를 바꿔 학년만 남긴 뒤 학과코드로 걸렀습니다. 학년만 남은 릴레이션에는 학과코드가 없어 걸 조건이 없습니다.
- ④ 기호의 자리와 차례를 모두 바꿔 썼습니다.
| 학년 |
|---|
| 1 |
| 3 |
다시 볼 레슨: 관계대수: 셀렉트·프로젝트·조인·디비전 · SELECT 기본: 조건과 정렬
문제 6
다음 문장을 처음 데이터에 돌렸을 때 점수가 바뀌는 행 수를 고르세요.
UPDATE 수강
SET 점수 = 점수 + 10
WHERE 점수 < 70;
- ① 4행
- ② 5행
- ③ 8행
- ④ 12행
정답
① — 70점 미만인 행은 102의 운영체제 60, 103의 자료구조 65, 103의 네트워크 55, 107의 네트워크 50 넷입니다. 각각 70·75·65·60으로 바뀝니다.
- ②
점수 < 70을점수 <= 70으로 읽었습니다. 70점인 102의 자료구조 행은 조건에 들지 않습니다. - ③ 조건을 거꾸로 읽어 70점 이상인 행을 셌습니다. 12행 가운데 넷이 70점 미만이라 나머지가 여덟입니다.
- ④ WHERE를 보지 않고 모든 행을 셌습니다. WHERE를 빼면 12행이 모두 10점씩 오릅니다.
다시 볼 레슨: DML: INSERT·UPDATE·DELETE
문제 7
어느 병원이 예약명부(예약번호, 환자이름, 진료과, 진료과전화) 한 표에 예약을 적습니다. 기본키는 예약번호이고, 내과 예약은 다섯 행입니다. 내과의 전화번호가 바뀌어 다음 문장을 돌렸습니다. 생기는 일과 그 이름으로 알맞은 것을 고르세요.
UPDATE 예약명부
SET 진료과전화 = '02-100'
WHERE 예약번호 = 3;
- ① 다섯 행이 모두 바뀌어 전화가 하나로 맞는다 · 삽입 이상
- ② 다섯 행이 모두 바뀌어 전화가 하나로 맞는다 · 갱신 이상
- ③ 한 행만 바뀌어 같은 진료과의 전화가 둘이 된다 · 삽입 이상
- ④ 한 행만 바뀌어 같은 진료과의 전화가 둘이 된다 · 갱신 이상
정답
④ — WHERE가 예약번호 3인 한 행만 고릅니다. 내과 전화라는 같은 사실이 다섯 행에 적혀 있어, 한 행만 고치면 같은 진료과의 전화가 둘이 됩니다. 일부만 고쳐 값이 어긋나는 문제가 갱신 이상입니다.
- ① 두 오해가 겹쳤습니다.
UPDATE는 WHERE에 맞는 행만 고치고, 이 문제의 이름은 갱신 이상입니다. - ② 같은 진료과의 행이 함께 따라 바뀐다고 봤습니다. 같은 값이 적힌 다른 행은 손대지 않습니다. 다섯 행을 맞추려면
WHERE 진료과 = '내과'로 고쳐야 합니다. - ③ 바뀌는 행은 맞게 짚고 이름을 바꿔 봤습니다. 삽입 이상은 넣고 싶은 정보만으로 행을 넣을 수 없는 문제입니다.
다시 볼 레슨: 이상 현상 · DML: INSERT·UPDATE·DELETE
문제 8
다음 쿼리의 결과는 몇 행인지 고르세요.
SELECT 학과코드,
COUNT(*) AS 인원
FROM 학생
GROUP BY 학과코드
ORDER BY 학과코드;
- ① 2행
- ② 3행
- ③ 4행
- ④ 7행
정답
② — GROUP BY는 같은 학과코드끼리 한 행으로 묶고, 학과코드가 NULL인 강도현도 NULL 그룹 하나로 묶습니다. CS·EE·NULL 세 그룹이라 3행입니다.
- ① NULL은 그룹을 만들지 않는다고 봤습니다.
COUNT(학과코드)가 NULL을 세지 않는 것과 달리, GROUP BY는 NULL끼리 한 그룹으로 묶습니다. - ③ 학과 표의 BA까지 0명으로 나온다고 봤습니다. FROM에는 학생 표뿐이라, 학생이 없는 BA는 묶을 행이 없어 나오지 않습니다.
- ④ GROUP BY가 같은 값끼리 모아 늘어놓기만 한다고 봤습니다. 묶은 뒤에는 그룹마다 한 행입니다.
| 학과코드 | 인원 |
|---|---|
| CS | 3 |
| EE | 3 |
| NULL | 1 |
다시 볼 레슨: 그룹과 집계: GROUP BY·HAVING
문제 9
다음 쿼리의 결과는 몇 행인지 고르세요.
SELECT 학년,
학과코드,
COUNT(*) AS 인원
FROM 학생
WHERE 학과코드 IS NOT NULL
GROUP BY ROLLUP(학년, 학과코드)
ORDER BY 학년, 학과코드;
- ① 4행
- ② 7행
- ③ 8행
- ④ 10행
정답
③ — WHERE가 강도현을 걸러 여섯 행이 남습니다. ROLLUP은 오른쪽 열부터 하나씩 빼며 (학년, 학과코드) · (학년) · () 세 묶음을 만듭니다. 상세가 4행, 학년별 소계가 3행, 총계가 1행이라 모두 8행입니다.
- ① 소계 줄과 총계 줄을 세지 않았습니다. 4행은 ROLLUP 없이 두 열로 묶은 결과입니다.
- ② 열 순서를 바꿔도 결과가 같다고 봤습니다.
ROLLUP(학과코드, 학년)이면 학과가 둘이라 소계가 2행이어서 7행입니다. - ④ CUBE로 묶었다고 봤습니다. CUBE라면 학과코드별 소계 2행이 더해져 10행입니다.
| 학년 | 학과코드 | 인원 |
|---|---|---|
| 1 | EE | 1 |
| 1 | NULL | 1 |
| 2 | CS | 2 |
| 2 | NULL | 2 |
| 3 | CS | 1 |
| 3 | EE | 2 |
| 3 | NULL | 3 |
| NULL | NULL | 6 |
다시 볼 레슨: 그룹 함수: ROLLUP·CUBE
문제 10
다음 쿼리의 결과 행 수와, 자료구조를 들은 101 행의 과목최고 값으로 알맞은 것을 고르세요.
SELECT 과목코드,
학번,
점수,
MAX(점수) OVER (
PARTITION BY 과목코드
) AS 과목최고
FROM 수강
WHERE 과목코드 IN ('DS', 'OS')
ORDER BY 과목코드, 학번;
- ① 2행 · 85
- ② 2행 · 100
- ③ 7행 · 85
- ④ 7행 · 100
정답
④ — 윈도우 함수는 행을 줄이지 않습니다. WHERE가 고른 일곱 행이 그대로 남고, 줄마다 그 과목 칸의 가장 높은 점수가 붙습니다. 자료구조 칸의 최고는 최민준의 100이라 101 행에도 100이 붙습니다.
- ① 두 오해가 겹쳤습니다. 행은 일곱 그대로이고, 붙는 값은 자기 점수가 아니라 칸 전체의 최고입니다.
- ② 과목마다 한 줄로 접힌다고 봤습니다. 한 줄로 접는 쪽은 GROUP BY이고, OVER를 붙인 집계 함수는 행을 그대로 둡니다.
- ③ 과목최고 자리에 그 행의 점수가 붙는다고 봤습니다. PARTITION BY로 나눈 칸의 최고가 그 칸의 모든 줄에 같은 값으로 붙습니다.
| 과목코드 | 학번 | 점수 | 과목최고 |
|---|---|---|---|
| DS | 101 | 85 | 100 |
| DS | 102 | 70 | 100 |
| DS | 103 | 65 | 100 |
| DS | 105 | 100 | 100 |
| OS | 101 | 75 | 75 |
| OS | 102 | 60 | 75 |
| OS | 104 | 75 | 75 |
다시 볼 레슨: 윈도우 함수
문제 11 (실기)
어느 회사가 쓰지 않는 부서 표를 없애려 합니다. 사원 표가 부서 표를 외래키로 가리키고, 부서 표로 만든 뷰도 하나 있습니다. (가)·(나)에서 DROP 문 끝에 적을 낱말을 SQL에 쓰는 꼴 그대로 쓰세요. 답을 끝까지 쓴 뒤 정답을 펼치세요.
- (가) 가리키는 것이 하나라도 있으면 부서 표를 없애지 말라고 할 때
- (나) 부서 표를 없애면서 사원 표의 그 외래키 제약 조건과 뷰까지 함께 없애라고 할 때
정답
받는 답: (가) RESTRICT · (나) CASCADE
(가)의 실마리는 '가리키는 것이 남아 있으면 그대로 두라', (나)는 '가리키던 제약 조건과 뷰까지 함께 치우라'입니다.
- 같은 이름의 다른 꼴: (가) 제한 · (나) 연쇄 — 한글로 읽은 이름입니다. 문제가 SQL에 쓰는 낱말로 물었습니다.
- 틀리는 꼴 CASCADE — (가)에: 가리키는 것이 있어도 없애면서 그 제약 조건과 뷰까지 함께 치우는 낱말입니다. (가)는 그대로 두라고 했습니다.
- 틀리는 꼴 ON DELETE CASCADE — (나)에: 부모 행을 지울 때 자식 행까지 지우라고 외래키에 미리 적어 두는 꼴입니다. 표를 없애는 DROP 문 끝에는 CASCADE 한 낱말만 적습니다.
다시 볼 레슨: DDL: CREATE·ALTER·DROP
문제 12 (실기)
어느 도서관의 대출 표에서 대출일수 열은 수만 담기로 해 두었습니다. 거기에 '이주일'이라는 글자를 넣으려 하자 DBMS가 거절했습니다. 이때 지켜진 규칙의 이름을 한글로 쓰세요. 답을 끝까지 쓴 뒤 정답을 펼치세요.
정답
받는 답: 도메인 무결성
실마리는 '그 열이 담기로 한 형식이 아닌 값을 넣었다'입니다. 속성이 가질 수 있는 값의 모임에는 값의 범위뿐 아니라 값의 형식도 들어갑니다.
- 같은 이름의 다른 꼴: Domain Integrity — 영문입니다. 문제가 한글로 물었습니다.
- 틀리는 꼴 개체 무결성: 행 하나를 가려내는 속성이 비거나 겹치는 것을 막는 규칙입니다. 대출일수는 행을 가려내는 속성이 아닙니다.
- 틀리는 꼴 CHECK: 담을 값을 적어 두는 제약 조건의 이름입니다. 묻는 것은 그 제약 조건이 지켜 주는 무결성의 이름입니다.
다시 볼 레슨: 무결성 제약 조건
문제 13 (실기)
다음 쿼리의 결과가 몇 행인지와, 각 행을 위에서부터 차례로 쓰세요. 답을 끝까지 쓴 뒤 정답을 펼치세요.
SELECT 과목코드,
COUNT(*) AS 인원,
SUM(점수) AS 합계,
MAX(점수) AS 최고,
MIN(점수) AS 최저
FROM 수강
WHERE 점수 >= 65
AND 과목코드
IN ('DS', 'NW', 'OS')
GROUP BY ROLLUP(과목코드)
HAVING COUNT(*) >= 3
ORDER BY GROUPING(과목코드),
과목코드;
정답
받는 답: 3행 — DS 4 · 320 · 100 · 65 / NW 3 · 265 · 95 · 80 / NULL 9 · 735 · 100 · 65
WHERE가 65점 미만인 60·55·50 세 행을 걸러 아홉 행이 남습니다. 묶으면 DS 4행, NW 3행, OS 2행이고 ROLLUP이 총계 줄을 붙입니다. HAVING이 3행 미만인 OS 묶음을 떨어뜨려 상세 둘과 총계 하나가 남습니다. 총계 줄은 WHERE를 지난 아홉 행을 모두 더한 값이라 OS의 두 행도 들어갑니다.
- 틀리는 꼴 OS 줄까지 쓴 네 행: HAVING이 2행뿐인 OS 묶음을 떨어뜨립니다. HAVING은 묶은 뒤 그룹을 거릅니다.
- 틀리는 꼴 총계 줄의 인원 7 · 합계 585: 떨어진 OS의 두 행을 총계에서도 뺀 꼴입니다. HAVING은 상세 묶음만 거르고 총계는 다시 세지 않습니다.
- 틀리는 꼴 총계 줄이 없는 두 행: ROLLUP이 맨 끝에 붙이는 총계 줄을 빠뜨렸습니다.
| 과목코드 | 인원 | 합계 | 최고 | 최저 |
|---|---|---|---|---|
| DS | 4 | 320 | 100 | 65 |
| NW | 3 | 265 | 95 | 80 |
| NULL | 9 | 735 | 100 | 65 |
다시 볼 레슨: 그룹 함수: ROLLUP·CUBE · 그룹과 집계: GROUP BY·HAVING