본문 바로가기
Archive/SQLD

[SQLD] 데이터 모델링의 이해 문제 (81-126)

by 우창욱 2024. 10. 19.

81. 아래 실행 결과를 출력하는 SQL로 가장 적절한 것은?

[설비]

설비ID 설비명
1 설비1
2 설비2
3 설비3

[에너지사용]

설비ID 에너지코드 사용량
1 전기 100
1 용수 200
1 바람 300
2 전기 200
2 용수 300
3 전기 300

[실행결과]

설비ID 에너지코드 사용량합계
1 바람 300
1 용수 200
1 전기 100
1 <NULL> 600
2 용수 300
2 전기 200
2 <NULL> 500
3 전기 300
3 <NULL> 300
<NULL> 바람 300
<NULL> 용수 500
<NULL> 전기 600
<NULL> <NULL> 1400

 

((A.설비ID), (B.에너지코드), (A.설비ID, B.에너지코드), (A.설비ID, B.에너지코드), (A.설비ID, (A.설비ID, B.에너지코드)), (B.에너지코드, (A.설비ID, B.에너지코드)), (A.설비ID, B.에너지코드, (A.설비ID, B.에너지코드)), ())

SELECT A.설비ID, B.에너지코드, SUM(B.사용량) AS 사용량합계
FROM 설비 A INNER JOIN 에너지사용량 B
ON (A.설비ID = B.설비ID)
GROUP BY CUBE((A.설비ID), (B.에너지코드), (A.설비ID, B.에너지코드));


((A.설비ID), (B.에너지코드), (A.설비ID, B.에너지코드), ())

SELECT A.설비ID, B.에너지코드, SUM(B.사용량) AS 사용량합계
FROM 설비 A INNER JOIN 에너지사용량 B
ON (A.설비ID = B.설비ID)
GROUP BY CUBE(A.설비ID, B.에너지코드)
ORDER BY A.설비ID, B.에너지코드;


((A.설비ID), (A.설비ID, B.에너지코드))

SELECT A.설비ID, B.에너지코드, SUM(B.사용량) AS 사용량합계
FROM 설비 A INNER JOIN 에너지사용량 B
ON (A.설비ID = B.설비ID)
GROUP BY GROUPING SETS((A.설비ID), (A.설비ID, B.에너지코드))
ORDER BY A.설비ID, B.에너지코드;


④ 

((A.설비ID), (B.에너지코드), (A.설비ID, B.에너지코드))

SELECT A.설비ID, B.에너지코드, SUM(B.사용량) AS 사용량합계
FROM 설비 A INNER JOIN 에너지사용량 B
ON (A.설비ID = B.설비ID)
GROUP BY GROUPING SETS((A.설비ID), (B.에너지코드), (A.설비ID, B.에너지코드))
ORDER BY A.설비ID, B.에너지코드;

 

82. 아래를 참고할 때 SQL의 빈칸 ㉠에 들어갈 내용으로 가장 적절한 것은?

[SQL]

SELECT A.JOB, A.DEPTNO, ROUND(AVG(A.SAL), 2) AVG_SAL
FROM EMP A
GROUP BY ㉠;

 

[실행 결과]

JOB DEPTNO AVG_SAL
CLERK 10 1300
CLERK 20 950
CLERK 30 950
ANALYST 20 3000
MANAGER 10 2450
MANAGER 20 2975
MANAGER 30 2850
SALESMAN 30 1400
PRESIDENT 10 5000
<NULL> <NULL> 2073.21

 

① ROLLUP(JOB, DEPTNO)

((JOB, DEPTNO), (JOB), ())
② ROLLUP((JOB, DEPTNO))

((JOB, DEPTNO), ())
③ ROLLUP((JOB), (DEPTNO))

((JOB, DEPTNO), (JOB), ())
④ JOB, ROLLUP (DEPTNO)

(JOB, DEPTNO), (JOB)

 

83. 아래 SQL의 실행 결과로 가장 적절한 것은?

[월별매출]

상품ID 매출액
P001 2014.10 1500
P001 2014.11 1500
P001 2014.12 2500
P002 2014.10 1000
P002 2014.11 2000
P002 2014.12 1500
P003 2014.10 2000
P003 2014.11 1000
P003 2014.12 1000

 

[SQL]

SELECT 상품ID, 월, SUM(매출액) AS 매출액
FROM 월별매출
WHERE 월 BETWWEN '2014.10' AND '2014.12'
GROUP BY GROUPING SETS((상품ID, 월));

GROUP BY GROUPING SETS((상품ID, 월)) = (상품ID, 월)

상품ID 매출액
<NULL> 2014.10 4500
<NULL> 2014.11 4500
<NULL> 2014.12 5000
P001 <NULL> 5500
P002 <NULL> 4500
P003 <NULL> 4000


상품ID 매출액
P001 2014.10 1500
P001 2014.11 1500
P001 2014.12 2500
P002 2014.10 1000
P002 2014.11 2000
P002 2014.12 1500
P003 2014.10 2000
P003 2014.11 1000
P003 2014.12 1000


상품ID 매출액
<NULL> 2014.10 4500
<NULL> 2014.11 4500
<NULL> 2014.12 5000
P001 <NULL> 5500
P002 <NULL> 4500
P003 <NULL> 4000
<NULL> <NULL> 14000


④ 

상품ID 매출액
P001 2014.10 1500
P002 2014.10 1000
P003 2014.10 2000
<NULL> 2014.10 4500
P001 2014.11 1500
P002 2014.11 2000
P003 2014.11 1000
<NULL> 2014.11 4500
P001 2014.12 2500
P002 2014.12 1500
P003 2014.12 1000
<NULL> 2014.12 5000

 

84. 윈도우 함수(Window Function)에 대한 설명으로 가장 적절하지 않은 것은?

① PARTITION BY 절과 GROUP BY 절은 의미적으로 유사하다.
② PARTITION BY 절이 없으면 전체 집합을 하나의 Partition으로 정의한 것과 동일하다.
③ 윈도우 함수 처리로 결과 건수가 줄어든다.

(윈도우 함수는 행들의 그룹(윈도우)에 대해 계산을 수행하지만, 결과 집합의 각 행을 유지한다.

이는 GROUP BY 절과는 다른 특성으로, GROUP BY는 실제로 결과 행을 줄일 수 있다.

윈도우 함수는 원본 데이터셋의 각 행에 대해 계산된 결과를 추가한다.

따라서 입력 행의 수와 출력 행의 수가 동일하게 유지된다.

윈도우 함수는 오히려 각 행에 추가적인 정보(ex. 순위, 누적합)를 제공한다.

이로 인해 결과 집합의 열 수는 증가할 수 있지만 행 수는 변하지 않는다.)
④ 윈도우 함수 적용 범위는 Partition을 넘을 수 없다.


(참고)

윈도우(분석) 함수

종류 이름 설명
순위 함수 ROW_NUMBER() 각 파티션 내에서 고유한 순위를 부여한다.
RANK() 동일한 값에 대해 같은 순위를 부여하고, 다음 순위는 건너뛴다.
DENSE_RANK() 동일한 값에 대해 같은 순위를 부여하고, 다음 순위를 건너뛰지 않는다.
오프셋 함수 LAG(column, n) 현재 행에서 n만큼 이전 행의 값을 반환한다.
LEAD(column, n) 현재 행에서 n만큼 이후 행의 값을 반환한다.
FIRST_VALUE(column) 윈도우의 첫 번째 행 값을 반환한다.
LAST_VALUE(column) 윈도우의 마지막 행 값을 반환한다.
집계 함수 SUM(), AVG(), COUNT(), MIN(), MAX()  
분석 함수 CUME_DIST() 누적 분포 값을 계산한다.
PERCENT_RANK() 백분율 순위를 계산한다.
NTILE(n) 데이터를 n개의 그룹으로 균등하게 나눈다.
이동 평균 함수 AVG() OVER (ORDER BY ... ROWS BETWEEN ...)) -
비율 함수 RATIO_TO_REPORT() 전체 합계에 대한 현재 값의 비율을 계산한다.

 


85. 아래 SQL의 실행 결과로 가장 적절한 것은?

[고객]

고객번호(PK) 고객명
001 홍길동
002 이순신
003 강감찬
004 이상화
005 이규혁

 

[월별 매출]

월(PK) 고객번호(PK) 매출액
201301 001 200
201301 002 300
201301 003 250
201301 004 300
201301 005 250
201302 001 150
201302 002 150
201302 004 200
201302 005 100
201303 002 100
201303 003 100
201303 004 200
201303 005 350

 

[SQL]

SELECT 고객번호, 고객명, 매출액, RANK() OVER(ORDER BY 매출액 DESC) AS 순위
FROM (
	SELECT A.고객번호, MAX(A.고객명) AS 고객명, SUM(B.매출액) AS 매출액
    FROM 고객 A INNER JOIN 월별매출 B
    ON (A.고객번호 = B.고객번호)
    GROUP BY A.고객번호
    )
ORDER BY 순위;

고객번호 고객명 매출액 순위
005 이규혁 700 1
004 이상화 700 1
002 이순신 550 3
001 홍길동 350 4
003 강감찬 350 4


고객번호 고객명 매출액 순위
005 이규혁 700 1
004 이상화 700 2
002 이순신 550 3
001 홍길동 350 4
003 강감찬 350 5


고객번호 고객명 매출액 순위
005 이규혁 700 1
004 이상화 700 1
002 이순신 550 2
001 홍길동 350 3
003 강감찬 350 3


④ 

고객번호 고객명 매출액 순위
003 강감찬 350 1
001 홍길동 350 1
002 이순신 550 2
004 이상화 700 3
005 이규혁 700 3

 

86. 아래를 참고할 때 SQL의 빈칸 ㉠에 들어갈 내용으로 가장 적절한 것은?

[실행 결과]

JOB ENAME SAL COMM RANK
PRESIDENT KING 5000 <NULL> 1
ANALYST FORD 3000 <NULL> 2
ANALYST SCOTT 3000 <NULL> 2
MANAGER JONES 2975 <NULL> 3
MANAGER BLAKE 2850 <NULL> 4
SALESMAN MARTIN 1250 1400 5
MANAGER CLARK 2450 <NULL> 6
SALESMAN ALLEN 1600 300 7
SALESMAN WARD 1250 500 8
SALESMAN TURNER 1500 0 9
CLERK MILLER 1300 <NULL> 10
CLERK ADAMS 1100 <NULL> 11
CLERK JAMES 950 <NULL> 12
CLERK SMITH 800 <NULL> 13

 

[SQL]

SELECT JOB, ENAME, SAL, COMM, ㉠ () OVER(ORDER BY NVL(SAL,0) + NVL(COMM,0) DESC) RANK
FROM EMP;

 

① ROWNUM
② ROW_NUMBER
③ RANK

④ DENSE_RANK


(참고)

NVL

  • NVL 함수는 첫 번째 인자가 NULL일 경우 두 번째 인자의 값을 반환한다.
  • expr1, expr2의 데이터 타입은 호환되어야 한다.

87. 아래를 참고할 때 SQL의 실행 결과로 가장 적절한 것은?

[추천내역]

추천경로 추천인 피추천인 추천점수
SNS 나한일 강감찬 75
SNS 이순신 강감찬 80
이벤트응모 홍길동 강감찬 88
이벤트응모 저절로 이순신 78
홈페이지 저절로 이대로 93
홈페이지 홍두깨 심청이 98

 

[SQL]

SELECT 추천경로, 추천인, 피추천인, 추천점수
FROM (SELECT 추천경로, 추천인, 피추천인, 추천점수,
	ROW_NUMBER() OVER(PARTITION BY 추천경로 ORDER BY 추천점수 DESC) AS RNUM
    FROM 추천내역)
WHERE RNUM = 1;

 

추천경로 추천인 피추천인 추천점수
SNS 나한일 강감찬 75
SNS 이순신 강감찬 80
이벤트응모 홍길동 강감찬 88
이벤트응모 저절로 이순신 78
홈페이지 저절로 이대로 93
홈페이지 홍두깨 심청이 98


추천경로 추천인 피추천인 추천점수
홈페이지 홍두깨 심청이 98


추천경로 추천인 피추천인 추천점수
SNS 이순신 강감찬 80
이벤트응모 홍길동 강감찬 88
홈페이지 홍두깨 심청이 98


④ 

추천경로 추천인 피추천인 추천점수
SNS 나한일 강감찬 75
이벤트응모 저절로 이순신 78
홈페이지 저절로 이대로 93

 

88. 아래 SQL에 대한 설명으로 가장 적절한 것은?

[SQL]

SELECT 상품분류코드, AVG(상품가격) AS 상품가격, 
	COUNT(*) OVER(ORDER BY AVG(상품가격) RANGE BETWEEN 10000 PRECEDING AND 10000 FOLLOWING) AS 유사개수
FROM 상품
GROUP BY 상품분류코드;

① WINDOW FUNCTION을 GROUP BY 절과 함께 사용하였으므로 위의 SQL은 오류가 발생한다.
② WINDOW FUNCTION의 ORDER BY 절에 AVG 집계 함수를 사용하였으므로 위의 SQL은 오류가 발생한다.
③ 유사개수 컬럼은 상품분류코드별 평균상품가격을 서로 비교하여 -10000 ~ +10000 사이에 존재하는 상품분류코드의 개수를 구한 것이다.
④ 유사개수 컬럼은 상품전체의 평균상품가격을 서로 비교하여 -10000 ~ +10000 사이에 존재하는 상품의 개수를 구한 것이다. (상품 전체가 아닌 상품분류코드별로 계산을 수행한다.)


(참고)

윈도우 함수와 ORDER BY 절을 함께 사용할 수 있다.

 

GROUP BY 절로 그룹화된 데이터에 대해 WINDOW FUNCTION을 사용할 수 있다.

 

RANGE BETWEEN 10000 PRECEDING AND 10000 FOLLOWING

  • RANGE 앞의 컬럼 값을 기준으로 -10000에서 +10000 사이의 범위를 지정한다.

89. 아래 SQL의 실행 결과로 가장 적절한 것은?

[사원]

사원ID 부서ID 사원명 연봉
001 100 홍길동 2500
002 100 강감찬 3000
003 200 김유신 4500
004 200 김선달 3000
005 200 유학생 2500
006 300 변사또 4500
007 300 박문수 3000

 

[SQL]

SELECT Y.사원ID, Y.부서ID, Y.사원명, Y.연봉
FROM (SELECT 사원ID, MAX(연봉) OVER(PARTITION BY 부서ID) AS 최고연봉
		FROM 사원) X, 사원 Y
WHERE X.사원ID = Y.사원ID
AND X.최고연봉 = Y.연봉;

사원ID 부서ID 사원명 연봉
002 100 강감찬 3000
003 200 김유신 4500
006 300 변사또 4500


사원ID 부서ID 사원명 연봉
001 100 홍길동 2500
005 200 유학생 2500
007 300 박문수 3000


사원ID 부서ID 사원명 연봉
003 200 김유신 4500
006 300 변사또 4500


④ 

사원ID 부서ID 사원명 연봉
003 200 김유신 4500

 

90. 아래를 참고할 때 SQL의 빈칸 ㉠에 들어갈 내용으로 가장 적절한 것은?

[SQL]

SELECT EMPNO, HIREDATE, SAL, ㉠ (SAL) OVER (ORDER BY HIREDATE) AS SAL2
FROM EMP
WHERE JOB = 'SALESMAN';

 

[실행결과]

EMPNO HIREDATE SAL SAL_2
7499 2018-02-20 1600 <NULL>
7521 2018-02-22 1250 1600
7844 2018-09-08 1500 1250
7654 2018-09-28 1250 1500

 

① LEAD
② ROW_NUMBER
③ RANK
④ LAG


(참고)

LEAD는 SQL Server에서는 지원하지 않는 함수이다.


 

91. GRANT와 REVOKE에 대한 설명으로 가장 적절하지 않은 것은?

① 어떤 사용자가 WITH GRANT OPTION과 함께 권한을 허가받았으면 그 사용자는 해당 권한을 WITH GRANT OPTION 유무와 관계없이 다른 사용자에게 허가할 수 있다.
② PUBLIC을 사용하면 자신에게 허가된 권한을 모든 사용자에게 허가할 수 있다.
③ REVOKE 문을 사용하여 권한을 취소하더라도 권한을 취소당한 사용자가 WITH GRANT OPTION을 통해서 다른 사용자에게 허가했던 권한들까지 연쇄적으로 모두 최소되는 것은 아니다.

(CASCADE REVOKE와 WITH GRANT OPTION

  • 일반적으로 데이터베이스 시스템에서는 CASCADE REVOKE라는 개념을 사용한다.
  • 이는 권한이 취소될 때, 해당 권한으로 인해 부여된 모든 하위 권한도 함께 취소되는 것을 의미한다.
  • WITH GRANT OPTION으로 부여된 권한이 취소되면, 그 권한을 통해 다른 사용자에게 부여된 권한도 연쇄적으로 취소된다.)

④ REVOKE 문을 사용하여 권한을 취소할 때, 그 권한을 허가한 사용자가 권한을 취소할 수 있다.

 

92. B_User가 아래의 작업을 수행할 수 있도록 권한을 부여하는 DCL로 가장 적절한 것은?

UPDATE A_User, TB_A
SET col1='AAA'
WHERE col2=3

① GRANT SELECT, UPDATE TO B_User;

(객체(테이블)를 지정하지 않아 불완전하다.)
② REVOKE SELECT ON A_User, TB_A FROM B_User;

(REVOKE는 권한을 제거하는 명령어다.)
③ DENY UPDATE ON A_User.TB_A TO B_User;

(DENY는 사용자나 역할에 대해 특정 권한을 명시적으로 거부하는 명령어이다.

GRANT의 반대 개념이다.

권한을 적극적으로 차단한다.

REVOKE는 이미 부여된 권한을 단순히 제거하는 것이며, DENY는 권한을 적극적으로 거부하여, 상위 레벨에서 GRANT로 부여된 권한도 무효화한다.)

④ GRANT SELECT, UPDATE ON A_User, TB_A TO B_User;

(쿼리가 UPDATE 문을 사용하기 때문에 필수적이고, WHERE 절을 사용해서 데이터를 필터링하므로 필요하다.

쿼리가 A_User, TB_A 테이블을 대상으로 하고 있다.)


(참고)

GRANT [권한] ON [객체] TO [사용자]


 

93. 아래는 EMPLOYEE 스키마뿐만 아니라 연관된 객체들도 모두 삭제하는 SQL 명령어 이다. 빈칸 ㉠에 들어갈 내용으로 가장 적절한 것은?

DROP SCHEMA EMPLOYEE ㉠;

① NULL

(컬럼의 정의에 사용되는 제약조건으로 스키마 삭제와는 관련이 없다.)
② NOT NULL

(컬럼의 정의에 사용되는 제약조건으로 스키마 삭제와는 관련이 없다.)
③ CASCADE
④ RESTRICT
(스키마에 종속 객체가 있으면 삭제를 거부한다. (CASCADE의 반대 개념))

 

94. 사용자 Lee가 테이블 R을 생성한 후 아래의 SQL을 실행하였다. 그 이후에 실행 가능한 SQL로 가장 적절한 것은? (단, A, B의 데이터 타입은 정수형이다.)

# Lee
GRANT SELECT, INSERT, DELETE ON R TO Kim WITH GRANT OPTION;
# Kim
GRANT SELECT, INSERT, DELETE ON R TO Park;
# Lee
REVOKE DELETE ON R FROM Kim CASCADE;
# Lee
REVOKE INSERT ON R FROM Kim CASCADE;

① Park: SELECT * FROM R WHERE A = 400;
② Park: INSERT INTO R VALUES(400, 600);
③ Park: DELETE FROM R WHERE B = 800;
④ Kim: INSERT INTO R VALUES(500, 600);

 

95. 아래 SQL과 동일한 결과를 출력하는 SQL로 가장 적절한 것은?

[SQL]

SELECT X.keyb, Y.col1, SUM(X.col1) as sumcol1
FROM Table_B, X, Table_A Y
WHERE X.keya = Y.keya
GROUP BY CUBE(X.keyb, Y.col1)
ORDER BY keyb, col1;

SELECT X.keyb, Y.col1, SUM(X.col1) AS sumcol1
FROM Table_B, X, Table_A Y
WHERE X.keya = Y.keya
GROUP BY ROLLUP(X.keyb, Y.col1)
ORDER BY keyb, col1;


SELECT X.keyb, Y.col1, SUM(X.col1) AS sumcol1
FROM Table_B, X, Table_A Y
WHERE X.keya = Y.keya
GROUP BY GROUPING SETS((X.keyb, Y.col1), (X.keyb), (Y.col1), ()) 
ORDER BY keyb, col1;


SELECT X.keyb, Y.col1, SUM(X.col1) AS sumcol1
FROM Table_B, X, Table_A Y
WHERE X.keya = Y.keya
GROUP BY X.keyb
UNION ALL
SELECT MAX(X.keyb) AS keyb, Y.col1, SUM(X.col1) AS sumcol1
FROM Table_B X, Table_A Y
WHERE X.keya = Y.keya
GROUP BY Y.col1
ORDER BY keyb, col1;


④ 

SELECT X.keyb, MAX(Y.col1) AS col1, SUM(X.col1) AS sumcol1
FROM Table_B X, Table_A Y
WHERE X.keya = Y.keya
GROUP BY X.keyb
UNION ALL
SELECT MAX(X.keyb) AS keyb, Y.col1, SUM(X.col1) AS sumcol1
FROM Table_B X, Table_A Y
WHERE X.keya = Y.keya
GROUP BY Y.col1
UNION ALL
SELECT X.keyb, Y.col1, SUM(X.col1) AS sumcol1
FROM Table_B X, Table_A Y
WHERE X.keya = Y.keya
GROUP BY X.keyb, Y.col1
ORDER BY keyb, col1;

 

96. 집합 연산자인 INTERSECT에 대한 설명으로 가장 적절한 것은?

① 여러 개의 SQL 문의 결과에 대한 합집합으로, 중복된 행은 하나의 행으로 출력한다.
② 여러 개의 SQL 문의 결과에 대한 합집합으로, 중복된 행도 그대로 결과로 출력한다.
③ 여러 개의 SQL 문의 결과에 대한 교집합으로, 중복된 행은 하나의 행으로 출력한다.
④ SQL문 결과간의 차집합으로, 중복된 행은 하나의 행으로 출력한다.

 

97. 아래를 참고할 때 SQL의 빈칸 ㉠에 들어갈 내용으로 가장 적절한 것은?

[emp]

EMPNO ENAME JOB SAL
7698 BLAKE MANAGER 2850
7782 CLARK MANAGER 2450
7566 JONES MANAGER 2975
7499 ALLEN SALESMAN 1600
7654 MARTIN SALESMAN 1250
7844 TURNER SALESMAN 1500
7521 WARD SALESMAN 1250

[SQL]

SELECT a.empno, a.ename, a.job, 
	LAG(a.sal, ㉠) OVER(PARTITION BY a.job ORDER BY a.ename) AS prev_sal
FROM emp a;

[실행 결과]

EMPNO ENAME JOB PREV_SAL
7698 BLAKE MANAGER <NULL>
7782 CLARK MANAGER <NULL>
7566 JONES MANAGER 2850
7499 ALLEN SALESMAN <NULL>
7654 MARTIN SALESMAN <NULL>
7844 TURNER SALESMAN 1600
7521 WARD SALESMAN 1250

① 0
② 1
③ 2
④ 4

 

98. 아래를 참고할 때, SQL의 빈칸 ㉠에 들어갈 내용으로 가장 적절한 것은?

[TBL]

COL1 COL2
1 100
2 100
3 200
4 300
5 300
6 300
7 400
8 500

 

[SQL]

SELECT COL1, COL2, ㉠ () OVER (ORDER BY COL2) COL3
FROM TBL;

 

[실행 결과]

COL1 COL2 COL3
1 100 1
2 100 1
3 200 3
4 300 4
6 300 4
5 300 4
7 400 7
8 500 8

 

① DENSE_RANK
② RANK
③ ROW_NUMBER
④ PERCENT_RANK

 

99. 아래 데이터 모델과 같은 테이블 및 PK 제약조건을 생성하는 DDL 문장으로 가장 적절한 것은?

(ALTER TABLE 구문이 잘못되었다. "ADD PRIMARY KEY PRODUCT_PK ON" 은 잘못된 형식이다.)

CREATE TABLE PRODUCT
(PROD_ID VARCHAR2(10) NOT NULL, 
	PROD_NM VARCHAR2(100) NOT NULL,
    REG_DT DATE NOT NULL,
    REGR_NO NUMBER(10) NULL );
ALTER TABLE PRODUCT ADD PRIMARY KEY PRODUCT_PK ON (PROD_ID);


(PROD_ID, PROD_NM, REG_DT에 NOT NULL 제약조건이 누락되었다.)

CREATE TABLE PRODUCT
(PROD_ID VARCHAR2(10), 
	PROD_NM VARCHAR2(100),
    REG_DT DATE,
    REGR_NO NUMBER(10) );
ALTER TABLE PRODUCT ADD CONSTRAINT PRODUCT_PK PRIMARY KEY (PROD_ID);


(ADD CONSTRAINT PRIMARY KEY 구문이 잘못되었다.

CREATE TABLE 내에서 이런 방식으로 기본키를 추가할 수 없다.

기본키에 PRODUCT_PK를 지정하지 않았다.)

CREATE TABLE PRODUCT
(PROD_ID VARCHAR2(10) NOT NULL,
	PROD_NM VARCHAR2(100) NOT NULL,
    REG_DT DATE NOT NULL,
    REGR_NO NUMBER(10) NULL,
    ADD CONSTRAINT PRIMARY KEY (PROD_ID));


④ 

CREATE TABLE PRODUCT
( PROD_ID VARCHAR2(10) NOT NULL,
	PROD_NM VARCHAR2(100) NOT NULL,
    REG_DT DATE NOT NULL,
    REGR_NO NUMBER(10),
    CONSTRAINT PRODUCT_PK PRIMARY KEY (PROD_ID));

(참고)

PK를 지정하는 방식

1. CONSTRAINT 키워드를 사용하는 방법

CREATE TABLE PRODUCT (
    PROD_ID VARCHAR2(10) NOT NULL,
    PROD_NM VARCHAR2(100) NOT NULL,
    REG_DT DATE NOT NULL,
    REGR_NO NUMBER(10),
    CONSTRAINT PRODUCT_PK PRIMARY KEY (PROD_ID)
);

2. CONSTRAINT 키워드를 사용하지 않는 방법

CREATE TABLE PRODUCT (
    PROD_ID VARCHAR2(10) NOT NULL PRIMARY KEY,
    PROD_NM VARCHAR2(100) NOT NULL,
    REG_DT DATE NOT NULL,
    REGR_NO NUMBER(10)
);

100. 아래와 같이 데이터가 들어있지 않은 왼쪽의 기관분류 테이블 (가)를 (나) 처럼 변경하고자 할 때 가장 적절한 SQL은?

(단 DBMS는 SQL Server로 가정)

ALTER TABLE 기관분류 ALTER COLUMN (분류명 VARCHAR(30), 등록일자 DATE NOT NULL);


ALTER TABLE 기관분류 ALTER COLUMN (분류명 VARCHAR(30) NOT NULL, 등록일자 DATE NOT NULL);


ALTER TABLE 기관분류 ALTER COLUMN 분류명 VARCHAR(30);
ALTER TABLE 기관분류 ALTER COLUMN 등록일자 DATE NOT NULL;


④ 

ALTER TABLE 기관분류 ALTER COLUMN 분류명 VARCHAR(30) NOT NULL;
ALTER TABLE 기관분류 ALTER COLUMN 등록일자 DATE NOT NULL;

(참고)

테이블 칼럼에 대한 정의 변경

  • Oracle
    • ALTER TABLE 테이블명 MODIFY (...)
    • ALTER TABLE 구문을 사용할 때 한 번에 여러 열을 변경할 수 있다.
  • SQL Server
    • ALTER TABLE 테이블명 ALTER (...)
    • ALTER TABLE 구문을 사용할 때 한 번에 여러 열을 변경할 수 없다.

101. 아래와 같은 상황에서 문제가 발생한 트랜잭션의 특성으로 가장 적절한 것은?

[TableA]

COL1 COL2
A 100
B 200

[트랜잭션]

시간 TX1 TX2
t1 update TableA set col2 = 200 where col1 = 'A';  
t2   update TableA set col2 = 300 where col1 = 'A';
t3   commit;
t4 commit;  

[트랜잭션 수행결과]

COL1 COL2
A 300
B 200

 

① 원자성 (Atomicity)
② 일관성 (Consistency)
③ 고립성 (Isolation)

(동시에 실행되는 트랜잭션들이 서로 영향을 미치지 않고 독립적으로 실행되는 것처럼 보이도록 하는 특성이다.

트랜잭션 격리 수준이 적절하지 않아 발생한 문제이다.)

④ 영속성 (Durability)


(참고)

ACID

이름 설명
원자성 (Atomicity) 트랜잭션의 모든 연산은 전부 성공하거나 전부 실패해야 한다.
트랜잭션 중 일부만 실행되는 부분 완료 상태가 있어서는 안된다.
ex) 은행 송금에서 출금과 입금이 모두 성공하거나 모두 실패해야 한다.
일관성 (Consistency) 트랜잭션 실행 전후의 데이터베이스 상태가 일관성을 유지해야 한다.
데이터베이스의 제약조건, 규칙 등이 항상 지켜져야 한다.
ex) 계좌 잔고가 항상 0이어야 한다는 규칙이 있다면, 트랜잭션 후에도 이 규칙이 지켜져야 한다.
고립성 (Isolation) 동시에 실행되는 트랜잭션들이 서로 영향을 미치지 않아야 한다.
각 트랜잭션은 다른 트랜잭션의 작업 내용을 알 수 없어야 한다.
ex) 두 사용자가 동시에 같은 데이터를 수정할 때, 서로의 작업이 간섭받지 않아야 한다.
영속성 (Durability) 트랜잭션이 성공적으로 완료(커밋)되면, 그 결과는 영구적으로 반영되어야 한다.
시스템 장애가 발생하더라도 커밋된 트랜잭션의 결과는 보존되어야 한다.
ex) 은행 거래가 완료된 후 시스템이 다운되어도, 재시작 후엔 그 거래내역이 유지되어야 한다.

 

102. 아래를 참고할 때 DELETE FROM T;를 수행한 후에 테이블 R에 남아있는 데이터로 가장 적절한 것은?

CREATE TABLE T
(C INTEGER PRIMARY KEY,
 D INTEGER);

 

CREATE TABLE S
(B INTEGER PRIMARY KEY,
 C INTEGER REFERENCES T(C) ON DELETE CASCASE);
CREATE TABLE R
(A INTEGER PRIMARY KEY,
 B INTEGER REFERENCES S(B) ON DELETE SET NULL);

 

[T]

C D
1 1
2 1

 

[S]

B C
1 1
2 1

[R]

A B
1 1
2 2

 

① (1, NULL)과 (2, 2)
② (1, NULL)과 (2, NULL)

(S 테이블의 모든 셀이 다 NULL이 된다.)
③ (2, 2)
④ (1, 1)


(참고)

ON DELETE CASCADE

  • 참조 무결성을 유지하기 위해 행 전체를 삭제하는 옵션이다.
  • 이 옵션이 설정된 경우 참조되는 테이블에서 행이 삭제되면, 참조하는 테이블에서 해당 행 전체가 삭제된다.
    • 특정 컬럼만 삭제되는 것이 아니라 그 행 전체가 삭제된다.

103. 아래 SQL의 실행 결과로 가장 적절한 것은?

[Table_A]

keya col1 col2
1 A 2
2 A 2
3 B 3
4 B 3
5 C 3

 

[SQL]

begin transaction;
save transaction sp1;
delete from Table_A where keya = 2;
save transaction sp2;
delete from Table_A where col1 = 'A';
delete from Table_A where col2 = 3;
rollback transaction sp2;
commit;
select count(*) as cnt from Table_A;

 

① 2
② 3
③ 4
④ 5

 

104. SQL에서 중복 행을 제거하는 데 사용되는 키워드로 가장 적절한 것은?

① UNIQUE
② SORT
③ ORDER BY
④ DISTINCT

 

105. 테이블 생성 시 주의해야 할 사항으로 가장 적절한 것은?

① 테이블명은 객체를 의미할 수 있는 적절한 이름을 사용하고, 가능한 복수형을 권고한다. (단수형을 권고한다.)
② 한 테이블 내에서는 칼럼명을 중복되게 지정할 수 있다. (중복되지 않아야 한다.)
③ 칼럼 뒤에 데이터 유형은 꼭 지정되어야 한다.
④ 벤더에서 사전에 정의한 예약어 (Reserved Word)도 쓸 수 있다. (예약어를 사용할 수 없다.)


(참고)

+ 테이블명과 칼럼명은 반드시 문자로 시작해야 하고, 벤더별로 길이에 대한 한계가 있다.

+ A-Z, a-z, 0-9, _, $, # 문자만 허용된다.


106. 아래 SQL을 수행했을 때, T1 테이블의 최종 건수로 가장 적절한 것은?

[T1]

EMPNO ENAME JOB SAL
7369 SMITH CLERK 800
7566 JONES MANAGER 2975

[T2]

EMPNO ENAME JOB SAL
7566 JONES MANAGER 2975
7788 SCOTT ANALYST 3000
7876 ADAMS CLERK 1100
7902 FORD ANALYST 3000

[SQL]

MERGE INTO T1 A
  USING T2 B ON (B.EMPNO = A.EMPNO)
  WHEN MATCHED THEN
	UPDATE SET A.SAL = B.SAL - 500
    	WHERE A.JOB = 'CLERK'
    DELETE
    	WHERE A.SAL < 2000
  WHEN NOT MATCHED THEN
  	INSERT (A.EMPNO, A.ENAME, A.JOB)
    VALUES (B.EMPNO, B.ENAME, B.JOB)
    	WHERE B.JOB = 'CLERK';

 

(설명)

아래 SQL 형태로 구분된다고 보면 된다.

MERGE INTO T1 A    
USING T2 B      
ON (B.EMPNO = A.EMPNO)  

WHEN MATCHED THEN
   UPDATE SET A.SAL = B.SAL - 500    
   WHERE A.JOB = 'CLERK'
   DELETE                            
   WHERE A.SAL < 2000

WHEN NOT MATCHED THEN             
   INSERT (A.EMPNO, A.ENAME, A.JOB)  
   VALUES (B.EMPNO, B.ENAME, B.JOB)
   WHERE B.JOB = 'CLERK';

(결과)

답안지는 행이 2개라는데 ORACLE 써보면 3개 나온다. (https://livesql.oracle.com/)

EMPNO ENAME JOB SAL
7369 SMITH CLERK 800
7566 JONES MANAGER 2975
7876 ADAMS CLERK <NULL>

① 1
② 2
③ 3
④ 4


(참고)

MERGE

  • 기준 테이블은 그대로 가져온다.
  • 조건에 따라 테이블에 INSERT, UPDATE, DELETE한 번에 수행할 수 있는 SQL 문이다.
  • 두 테이블을 비교하여 데이터를 동기화할 때 주로 사용된다.
  • 하나의 SQL 문으로 여러 DML(Data Manipulation Language) 작업을 수행할 수 있어 효율적이다.

INTO

  • MERGE 문에서 데이터가 입력/수정/삭제될 대상 테이블을 지정한다.
  • "MERGE INTO 테이블명" 형식으로 사용된다.
  • 이 테이블이 메인 테이블(타겟 테이블)이 된다.

MATCHED

  • WHEN MATCHED THEN
    • 두 테이블을 비교했을 때 조건이 일치하는 경우 실행할 작업을 정의한다.
    • 주로 UPDATEDELETE 작업을 수행한다.
    • ex) ON(B.EMPNO = A.EMPNO) 처럼 매칭 조건을 지정한다.
  • WHEN NOT MATCHED THEN
    • 조건이 일치하지 않는 경우 실행할 작업을 정의한다.
    • 주로 INSERT 작업을 수행한다.
    • 소스 테이블에는 있지만 타겟 테이블에 없는 데이터를 처리한다.

DELETE

  • MATCHED 조건에서 사용될 때, 조건에 맞는 행을 삭제한다.
  • MERGE 문에서는 UPDATE 이후에 DELETE가 수행된다.
  • WHERE 절과 함께 사용하여 특정 조건에 맞는 데이터만 삭제할 수 있다.

107. 아래와 같이 테이블을 생성한 후 데이터를 삽입했을 때, (가)와 (나)의 실행 결과에 대한 설명으로 가장 적절한 것은?

CREATE TABLE 학생 (학번 CHAR(8) PRIMARY KEY, 장학금 INTEGER);

(가)

SELECT COUNT(*) FROM 학생

(나)

SELECT COUNT(학번) FROM 학생;

(설명)

학번 컬럼이 PRIMARY KEY로 지정되어 있다.

PRIMARY KEY의 특성

  • NULL 값을 가질 수 없다.
  • 중복된 값을 가질 수 없다.
  • 반드시 값이 존재해야 한다.

COUNT의 특성

  • COUNT(*): 전체 행의 수를 카운트 한다.(NULL 포함)
  • COUNT(컬럼명): 해당 컬럼의 NULL이 아닌 값의 수를 카운트 한다.

 

① (가), (나) 문장의 실행 결과는 다를 수 있으며, 이유는 장학금 속성에 NULL이 존재할 수 있기 때문이다.
② (가), (나) 문장의 실행 결과는 항상 다르다.
③ (가), (나) 문장의 실행 결과는 항상 같다.
④ (가), (나) 문장의 실행 결과는 다를 수 있으며, 그 이유는 학번 속성에 NULL이 존재할 수 있기 때문이다.

 

108. 외래키에 대한 설명으로 가장 적절하지 않은 것은?

① 테이블 생성 시 설정할 수 있다.
② 외래키 값은 NULL을 가질 수 없다. (외래키, FOREIGN KEY는 NULL을 가질 수 있다.)
③ 한 테이블에 하나 이상 생성할 수 있다.
④ 외래키 값은 참조 무결성 제약을 받을 수 있다.

(참조하는 테이블의 기본키 값만을 가질 수 있다.

부모 테이블 데이터를 삭제하면 CASCADE, SET NULL 등의 옵션을 설정할 수 있다.)

 

109. 아래 SQL에서 RepName 속성이 가지는 키 특성으로 가장 적절한 것은?

CREATE TABLE SALESREP (
SalesRepNo      int         NOT NULL,
RepName         char(35)    NOT NULL,
HireDate        date        NOT NULL,

CONSTRAINT      SalesRepPK  PRIMARY KEY (SalesRepNo),
CONSTRAINT      SalesRepAK1 UNIQUE (RepName)
);

(설명)

RepName 컬럼

  • NOT NULL 제약조건이 있다.
  • UNIQUE 제약조건이 있다.
  • PRIMARY KEY는 SalesRepPK로 존재하고 있다.

 

① 기본키(Primary Key)
② 외래키 (Foreign Key)

③ 후보키 (Candidate Key)
④ 대리키 (Surrogate Key)


(참고)

이름 설명
슈퍼키 (Super Key) 튜플을 유일하게 식별할 수 있는 속성 또는 속성들의 집합이다.
최소성을 만족하지 않아도 된다.
ex) {학번}, {학번, 이름}, {학번, 이름, 학과}
후보키 (Candidate Key) 튜플을 유일하게 식별할 수 있는 최소한의 속성들의 집합이다.
슈퍼키 중에서 최소성을 만족하는 키이다.
유일성과 최소성을 만족한다.
ex) {학번}, {주민등록번호}
기본키 (Primary Key) 후보키 중에서 선택한 메인 키이다.
한 테이블에 하나만 존재할 수 있다.
NULL 값을 가질 수 없다.
ex) 학번을 PK로 지정한다.
대체키 (Alternate Key) 후보키 중에서 기본키로 선택되지 않은 나머지 키이다.
ex) 주민등록번호 (기본키가 학번이라면)
외래키 (Foreign Key) 다른 테이블의 기본키를 참조하는 속성이다.
NULL 값을 허용한다.
참조 무결성 제약조건을 가진다.
ex) 수강테이블의 학번(학생테이블을 참조한다.)
복합키 (Composite Key) 2개 이상의 속성을 조합하여 만든 키이다.
ex) 수강테이블 (학번 + 과목코드)
대리키 (Surrogate Key) 인위적으로 만든 식별자이다.
보통 일련번호 형식이다.
실제 데이터와는 상관없는 식별 목적이다.
ex) 자동으로 증가하는 ID 컬럼

110. 아래 테이블에서 COMM 컬럼을 삭제하고자 할 때, SQL의 빈칸 ㉠, ㉡에 들어갈 내용으로 가장 적절한 것은?

[EMP]

MGR ENAME SAL COMM
7566 FORD 3000 <NULL>
7566 SCOTT 3000 <NULL>
7698 JAMES 950 <NULL>
7698 ALLEN 1600 <NULL>
7698 WARD 1250 <NULL>
7698 TURNER 1500 <NULL>
7698 MARTIN 1250 <NULL>
7782 MILLER 1300 <NULL>
7788 ADAMS 1100 <NULL>
7839 JONES 2980 <NULL>
7839 CLARK 2450 <NULL>
7902 SMITH 800 <NULL>
<NULL> KING 5000 <NULL>

[SQL]

㉠ TABLE EMP ㉡ COMM;

(설명)

  • 테이블 구조 변경은 ALTER(DDL)이다.
  • 컬럼 삭제는 DROP COLUMN이 표준 SQL 문법이다.
  • MODIFY컬럼의 데이터 타입을 변경할 때 사용한다.
  • REMOVE표준 SQL에서 컬럼 삭제 시 사용하지 않는 키워드이다.

① ALTER, DROP COLUMN
② ALTER, REMOVE COLUMN
③ MODIFY, DROP COLUMN
④ MODIFY, REMOVE COLUMN


(참고)

DROP: 가장 일반적인 삭제 키워드이다.

  • 테이블 삭제: DROP TABLE
  • 컬럼 삭제: DROP COLUMN
  • 뷰 삭제: DROP VIEW
  • 인덱스 삭제: DROP INDEX

DELETE: 데이터(행)를 삭제한다.

  • 테이블의 데이터를 삭제: DELETE FROM

TRUNCATE: 테이블의 모든 데이터를 삭제한다.

  • 테이블 데이터 전체 삭제: TRUNCATE TABLE

ALTER ... DROP: 구조 변경 시 삭제한다.

  • 제약조건 삭제: ALTER TABLE ... DROP CONSTRAINT
  • 컬럼 삭제: ALTER TABLE ... DROP COLUMN

111. 아래 SQL의 실행 결과로 가장 적절한 것은?

[T1]

COL1 COL2
1 AAAA
1 AAAA
1 AAAA
1 BBBB

 

[SQL]

SELECT COUNT(COL1) AS CNT1, COUNT(COL2) AS CNT2
FROM (
	SELECT DISTINCT COL1, COL2 
    FROM T1
);

(설명)

SELECT DISTINCT는 지정된 모든 컬럼의 조합이 유일한 것만 남긴다.

 

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

 

112. SQL에서 사용되는 표준 데이터 타입으로 가장 적절하지 않은 것은? (단, DBMS는 오라클로 가정)

① Text

(Oracle에서 지원하지 않는 타입이다.

MySQL, PostgreSQL 등 다른 DBMS에서 사용한다.

Oracle에서는 CLOB를 대신 사용해야 한다.

 

Oracle에서 사용하는 문자형 데이터 타입

CHAR: 고정 길이 문자열

VARCHAR2: 가변 길이 문자열

CLOB: 대용량 문자열)
② Char (Oracle에서 지원한다.)
③ Varchar2 (Oracle에서 권장하는 가변 길이 타입이다.)
④ Numeric (Oracle에서 지원한다.)

 

113. 관계형 데이터베이스에서 자식 테이블의 FK 데이터 생성시 부모 테이블에 PK가 없는 경우, 자식 테이블 데이터 입력을 허용하지 않는 참조동작 (Referential Action)은?

① CASCADE
② RESTRICT
③ AUTOMATIC
④ DEPENDENT


(참고)

참조동작

  • 부모-자식 테이블 간의 참조 무결성을 유지하기 위한 규칙이다.
  • 자식 테이블은 FK를 통해 부모 테이블의 PK를 참조한다.
  • 주요 동작
    • CASCADE
      • 부모 테이블의 데이터가 변경/삭제되면 자식 테이블도 자동으로 변경/삭제된다.
    • RESTRICT
      • 자식 테이블이 참조중인 부모 테이블의 데이터 삭제/수정을 제한한다.
    • DEPENDENT
      • 부모 테이블에 없는 값을 자식 테이블이 참조하려 할 때 입력을 제한한다.
    • AUTOMATIC
      • 부모 테이블에 PK가 없는 경우 PK를 생성한 후에 자식 테이블에 입력한다.
    • NO ACTION
      • 참조 무결성을 위반하는 입력 액션을 허용하지 않는다.
    • SET NULL
      • 부모 테이블의 데이터가 변경/삭제되면 자식 테이블의 해당 외래키 값이 NULL로 설정된다.
    • SET DEFAULT
      • 부모 테이블의 데이터가 변경/삭제되면 자식 테이블의 해당 외래키 값이 미리 정의된 기본값으로 설정된다.

 

114. 아래를 참고할 때 오류가 발생하지 않는 SQL은?

CREATE TABLE TBL
(
	ID NUMBER PRIMARY KEY,
    AMT NUMBER NOT NULL,
    DEGREE VARCHAR2(1)
);

INSERT INTO TBL VALUES(1, 100); #(가)
INSERT INTO TBL(ID, AMT, DEGREE) VALUES(2, 200, 'AB'); #(나)
INSERT INTO TBL(ID, DEGREE) VALUES(4, 'X') #(다)
INSERT INTO TBL(ID, AMT) VALUES(3, 300); #(라)
INSERT INTO TBL VALUES(5, 500, NULL); #(마)

(설명)

(가)

  • 오류가 발생한다.
  • 테이블은 3개 컬럼인데 2개 값만 제공했다.

(나)

  • 오류가 발생한다.
  • DEGREE 컬럼은 VARCHAR2(1)인데 'AB'는 2글자이다.
  • 데이터 길이를 초과했다.

(다)

 

  • 오류가 발생한다.
  • AMT 컬럼이 NOT NULL인데 값을 제공하지 않는다.

 

(라)

 

  • 정상적으로 실행된다.
  • DEGREE는 NULL 허용이므로 생략이 가능하다.

 

(마)

 

  • 정상적으로 실행된다.
  • DEGREE는 NULL을 허용한다.

 

 

① (가), (나)
② (나), (다)
③ (다), (라)
④ (라), (마)

 

115. 아래를 참고할 때 오류가 발생하는 SQL은?

① INSERT INTO BOARD VALUES(1, 'Q&A', 'Y', SYSDATE, 'Q&A 게시판');
② INSERT INTO BOARD (BOARD_ID, BOARD_NM, USE_YN, BOARD_DESC) VALUES ('100', 'FAQ', 'Y', 'FAQ 게시판'); (REG_DATE는 NOT NULL 조건이 있다.)
③ UPDATE BOARD SET USE_YN = 'N' WHERE BOARD_ID = '1';
④ UPDATE BOARD SET BOARD_ID = 200 WHERE BOARD_ID = '100';

 

116. 아래를 참고할 때 오류가 발생하는 INSERT 문으로 가장 적절한 것은?

CREATE TABLE 주문 (
	주문번호 NUMBER PRIMARY KEY,
    주문일자 DATE NOT NULL,
    회원번호 NUMBER,
    주문상태코드 VARCHAR2(3) DEFAULT '000'
);

① INSERT INTO 주문(주문번호, 주문일자, 회원번호, 주문상태코드) VALUES(1, SYSDATE, 1900123, '002');

(SYSDATE는 현재 날짜를 반환하는 유효한 DATE 타입이다.)
② INSERT INTO 주문(주문번호, 주문일자, 회원번호, 주문상태코드) VALUES(2, '20190301', 1900124, '001');

(문자열 '20190301'은 자동으로 DATE 타입으로 변환된다.)
③ INSERT INTO 주문(주문번호, 주문일자, 회원번호, 주문상태코드) VALUES(3, SYSDATE-1, 1900125, '001');

(SYSDATE - 1은 어제 날짜를 의미하는 유효한 DATE 연산이다.)
④ INSERT INTO 주문(주문번호, 주문일자, 회원번호, 주문상태코드) VALUES(4, 20190302, 1900126, '001');

(숫자 20190302는 DATE 타입으로 자동 변환되지 않는다. 날짜는 문자열이나 DATE 함수 형태로 제공해야 한다.)

 

117. 아래의 산술 연산자를 우선순위가 높은 순으로 나열한 것은?

*, +, -, (), /

① *, /, +, -, ()
② +, -, *, /, ()
③ (), *, /, +, -
④ (), +, -, *, /

 

118. 아래와 같은 테이블에서 Department의 did가 '1'인 행이 삭제될 때, Employee의 did가 '1'인 행도 같이 삭제하도록 하는 방법으로 가장 적절한 것은? (단, Employee의 did는 Department에서 가져온 외래키이다.)

Employee(eid, ename, did)
Department(did, dname, budge)

① Employee 릴레이션을 생성할 때, FOREIGN KEY(did) REFERENCES Department(did) ON DELETE RESTRICT 명령어를 추가한다.
② Department 릴레이션을 생성할 때 FOREIGN KEY(did) REFERENCES Employee(did) ON DELETE CASCADE 명령어를 추가한다.
③ Employee 릴레이션을 생성할 때 FOREIGN KEY(did) REFERENCES Department(did) ON DELETE CASCADE 명령어를 추가한다.
④  Department 릴레이션을 생성할 때 FOREIGN KEY(did) REFERENCES Employee(did) ON DELETE RESTRICT 명령어를 추가한다.

 

119. DELETE와 TRUNCATE, DROP 명령어에 대해 비교한 설명으로 가장 적절하지 않은 것은?

① 특정 테이블에 대하여 WHERE 조건절이 없는 DELETE 명령을 수행하면 DROP TABLE 명령을 수행했을 때와 똑같은 결과를 얻을 수 있다.

(WHERE 절이 없는 DELETE는 모든 데이터만 삭제한다. 그러니 DROP은 테이블 자체를 삭제한다.)
② DROP 명령어는 테이블 정의 자체를 삭제하고, TRUNCATE 명령어는 테이블을 초기 상태로 만든다.

(DROP은 테이블 구조와 데이터를 모두 삭제한다. ROLLBACK이 불가능하다.)
③ TRUNCATE 명령어는 UNDO를 위한 데이터를 생성하지 않기 때문에 동일 데이터량 삭제 시 DELETE보다 빠르다.

(TRUNCATE는 테이블 구조만 유지하고, 디스크 공간을 즉시 해제한다. ROLLBACK이 불가능하다.)
④ DROP과 TRUNCATE는 Auto Commit되고, DELETE는 사용자 Commit으로 수행된다.

 

120. 데이터베이스 트랜잭션에 대한 설명으로 가장 적절하지 않은 것은?

① 원자성(Atomicity): 트랜잭션에 정의된 연산들은 모두 성공적으로 실행되든지 아니면 전혀 실행되지 않은 상태로 남아 있어야 한다.
② 일관성(Consitency): 트랜잭션이 실행 되기 전의 데이터베이스 내용이 잘못 되어 있지 않다면 트랜잭션이 실행된 이후에도 데이터베이스의 내용에 잘못이 있으면 안된다.
③ 고립성(Isolation): 트랜잭션이 실행되는 도중에 다른 트랜잭션의 영향을 받아 잘못된 결과를 만들어서는 안 된다.
④ 지속성(Durability): 트랜잭션을 취소하더라도 트랜잭션이 갱신한 내용이 데이터베이스에 저장되어야 한다.

 

121. 아래 SQL 실행 결과 테이블 A의 ID '001'에 해당하는 최종 VAL의 값이 오라클에서는 200, SQL Server에서는 100이 되었다고 할 때, 이에 대한 설명으로 가장 적절하지 않은 것은?

[A]

ID(PK) VAL
001 100
002 200

[SQL]

UPDATE A SET VAL = 200 WHERE ID = '001';
CREATE TABLE B (ID CHAR(3) PRIMARY KEY);
ROLLBACK;

① 오라클에서 CREATE TABLE 문장을 수행한 후, 묵시적으로 COMMIT이 수행되어 VAL값은 200이 되었다.
② SQL Server에서는 ROLLBACK 문장에 의해 UPDATE가 취소되어 VAL 값은 100이 되었다.
③ 오라클에서는 CREATE TABLE 문장 수행에 의해 VAL 값은 200이 되었지만, ROLLBACK 실행으로 최종적으로 B 테이블은 생성되지 않았다.
④ SQL Server 에서는 ROLLBACK 실행으로 인하여 UPDATE가 취소되었으며, 최종적으로 B 테이블은 생성되지 않았다.

 

122. 데이터베이스의 논리적 연산 단위를 가리키는 용어로 가장 적절한 것은?

① 뷰(View)
② 트랜잭션(Transaction)
③ 프로시저(Procedure)
④ 트리거(Trigger)

 

123. 아래 SQL의 실행 결과로 가장 적절한 것은?

[품목]

품목ID 단가
001 1000
002 2000
003 1000
004 2000

[SQL]

BEGIN TRANSACTION
INSERT INTO 품목(품목ID, 단가) VALUES('005', 2000)
COMMIT
BEGIN TRANSACTION
DELETE 품목 WHERE 품목ID='002'
BEGIN TRANSACTION
UPDATE 품목 SET 단가=2000 WHERE 단가=1000
ROLLBACK
SELECT COUNT(품목ID) FROM 품목 WHERE 단가=2000;

① 0
② 2
③ 3
④ 4

 

124. 아래를 참고할 때 상품ID의 '001'의 최종 상품명으로 가장 적절한 것은?

[상품]

상품ID 상품명
001 TV

[SQL]

BEGIN TRANSACTION
SAVE TRANSACTION SP1;
UPDATE 상품 SET 상품명='LCD-TV' WHERE 상품ID='001';
SAVE TRANSACTION SP2;
UPDATE 상품 SET 상품명='평면-TV' WHERE 상품ID='001';
ROLLBACK TRANSACTION SP2;
COMMIT;

① TV
② LCD-TV
③ 평면-TV
④ 오류가 발생한다.

 

125. 아래 테이블에서 승리건수가 높은 순으로 3위까지 출력하되 3위의 승리건수가 동일한 팀이 있다면 함께 출력하기 위한 SQL로 가장 적절한 것은?

[팀별성적]

팀명 승리건수 패배건수
A팀 120 80
B팀 20 180
C팀 10 190
D팀 100 100
E팀 110 90
F팀 100 100
G팀 70 130

(단순히 상위 3개 레코드만 출력된다. 동순위가 처리되지 않는다.)

SELECT TOP(3) 팀명, 승리건수
FROM 팀별성적
ORDER BY 승리건수 DESC;


(ORDER BY 절이 없어 정렬되지 않는다. 동순위가 처리되지 않는다.)

SELECT TOP(3) 팀명, 승리건수
FROM 팀별성적;


(정렬 전에 ROWNUM 조건이 적용되어 부적절 하다. 동순위가 처리되지 않는다.)

SELECT 팀명, 승리건수
FROM 팀별성적
WHERE ROWNUM <= 3
ORDER BY 승리건수 DESC;


④ (TOP(3)로 상위 3개 순위가 지정된다. WITH TIES로 동순위를 포함한다. ORDER BY로 올바르게 정렬한다.)

SELECT TOP(3) WITH TIES 팀명, 승리건수
FROM 팀별성적
ORDER BY 승리건수 DESC;

 

126. 부서 테이블의 담당자 변경을 위해 부서임시 테이블에 입력된 데이터를 활용하여 주기적으로 부서 테이블을 실행 결과와 같이 반영하기 위한 SQL로 가장 적절한 것은? (단, 부서임시 테이블에서 변경일자를 기준으로 가장 최근에 변경된 데이터를 기준으로 부서 테이블에 반영되어야 한다.)

[부서]

부서코드(PK) 부서명 상위부서코드 담당자
A001 대표이사 <NULL> 김대표
A002 영업본부 A001 홍길동
A003 경영지원본부 A001 이순신
A004 마케팅본부 A001 강감찬
A005 해외영업팀 A002 이청용
A006 국내영업팀 A002 박지성
A007 총무팀 A003 차두리
A008 인사팀 A003 이민정
A009 해외마케팅팀 A004 이병헌
A010 국내마케팅팀 A004 차승원

[부서임시]

변경일자(PK) 부서코드(PK) 담당자
2014.01.23 A007 이달자
2015.01.25 A007 홍경민
2015.01.25 A008 유재석

[실행 결과]

부서코드(PK) 부서명 상위부서코드 담당자
A001 대표이사 <NULL> 김대표
A002 영업본부 A001 홍길동
A003 경영지원본부 A001 이순신
A004 마케팅본부 A001 강감찬
A005 해외영업팀 A002 이청용
A006 국내영업팀 A002 박지성
A007 총무팀 A003 홍경민
A008 인사팀 A003 유재석
A009 해외마케팅팀 A004 이병헌
A010 국내마케팅팀 A004 차승원

(서브쿼리에서 부서코드를 선택하고 있음)

UPDATE 부서 A SET 담당자 = (SELECT C.부서코드 FROM 
	(SELECT 부서코드, MAX(변경일자) AS 변경일자
    	FROM 부서임시
        GROUP BY 부서코드) B, 부서임시 C
    WHERE B.부서코드 = C.부서코드
    AND B.변경일자 = C.변경일자
    AND A.부서코드 = C.부서코드);


(서브쿼리에서 부서코드를 선택하고 있음)

UPDATE 부서 A SET 담당자 = (SELECT C.부서코드 FROM
	(SELECT 부서코드, MAX(변경일자) AS 변경일자 
    	FROM 부서임시
        GROUP BY 부서코드) B, 부서임시 C
    WHERE B.부서코드 = C.부서코드
    AND B.변경일자 = C.변경일자
    AND A.부서코드 = C.부서코드)
WHERE EXISTS (SELECT 1 FROM 부서 X WHERE A.부서코드 = X.부서코드);


③ (부서임시 테이블에서 각 부서코드별 최신 변경일자의 담당자를 찾는다.

부서임시 테이블에 있는 부서코드만 업데이트 된다.

MAX를 사용하여 각 부서의 가장 최근 변경일자를 동적으로 찾는다.)

UPDATE 부서 A SET 담당자 = (SELECT B.담당자 
	FROM 부서임시 B
    WHERE B.부서코드 = A.부서코드
    AND B.변경일자 = (SELECT MAX(C.변경일자)
    	FROM 부서임시 C
        WHERE
        C.부서코드 = B.부서코드))
WHERE 부서코드 IN (SELECT 부서코드 FROM 부서임시);


(하드코딩된 변경일자 '2015.01.25'를 사용하면 부서임시 테이블의 모든 데이터가 적용되지 않는다.)

UPDATE 부서 A SET 담당자 = (SELECT B.담당자
	FROM 부서임시 B
    WHERE B.부서코드 = A.부서코드
    AND B.변경일자 = '2015.01.25');