Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Archives
Today
Total
관리 메뉴

쟝이의 세상

SQLD 기출문제 2과목(41~52) 오답정리 본문

자격증

SQLD 기출문제 2과목(41~52) 오답정리

zyangee 2024. 8. 16. 21:18
41. 아래를 참고할 때 시간별 사용량 테이블을 기반으로 고객별 사용금액을 출력하는 SQL로 가장 적절한 것은?








 

예시 테이블

** FROM 절을 제외하고 모두 같기 때문에 FROM 절만 보고 답을 고르면 된다!
     -> INNER JOIN 구문을 묻는 문제임을 알 수 있다.

⓵
INNER JOIN 시간대구간 C ON (B.사용시간대 <= C.시작시간대 AND  B.사용시간대 >= C.종료시간대)

 
예를 들어, B.사용시간대가 15:00인 경우 시간대구간 C에서는 12:00~16:00에 들어갈 수 있다.
'C.종료시간대 ≤ B.사용시간대 ≤ C.시작시간대' 라고 볼 수 있는데 '16:00 ≤ 15:00 ≤ 12:00' 는 맞지 않는 표현식이다. 
= 오류

⓶
INNER JOIN 시간대별사용량 B
INNER JOIN 시간대구간 C ON (A.고객ID = B.고객ID AND B.사용시간대 BETWEEN C.시작시간대 AND C.종료시간대)

INNER JOIN ~ ON ~ INNER JOIN ~ ON ~ : 하나의 JOIN에 ON으로 조건을 꼭 붙여줘야 한다.
= INNER JOIN 구문 오류

⓷
INNER JOIN 시간대별사용량 B ON (A.고객ID = B.고객ID)
INNER JOIN 시간대구간 C ON B.사용시간대 BETWEEN C.시작시간대 AND C.종료시간대

고객 A와 시간대별사용량 B를 고객ID 컬럼으로 연결
시간대별사용량 B와 시간대구간 C을 조인하여, B.사용시간대가 C.시작시간대와 C.종료시간대 구간에 포함되는 행 추출

예시 테이블의 결과값
⓸
INNER JOIN 시간대별사용량 B ON (A.고객ID = B.고객ID)
BETWEEN JOIN 시간대구간 C

BETWEEN JOIN 구문은 존재하지 않음!


42. 실행 결과가 다른 하나는?
⓵ 
SELECT    T.REGION_NAME, T.TEAM_NAME, T.STADIUM_ID, S.STADIUM_NAME
FROM       TEAM T INNER JOIN STADIUM S USING (T.STADIUM_ID = S.STADIUM_ID);

SELECT    TEAM.REGION_NAME, TEAM.TEAM_NAME, TEAM.STADIUM_ID, STADIUM.STADIUM_NAME
FROM       TEAM INNER JOIN STADIUM ON (TEAM.STADIUM_ID = STATIDUM.STADIUM_ID)

SELECT    T.REGION_NAME, T.TEAM_NAME, T.STADIUM_ID, S.STADIUM_NAME
FROM       TEAM T, STADIUM S
WHERE     T.STADIUM_ID = S.STADIRUM_ID

SELECT    TEAM.REGION_NAME, TEAM.TEAM_NAME, TEAM.STADIUM_ID, STADIUM.STADIUM_NAME
FROM       TEAM, STADIUM
WHERE     TEAM.STADIUM_ID = STADIUM.STADIUM_ID

 
USING절 : 두 테이블의 컬럼명이 같을 경우 조인 조건을 길게 적지않고 간단히 적을 수 있도록 하는 역할
 -> ON절과 비슷하다고 볼 수 있다.
 -> 반드시 괄호 안에 사용

**WHERE절**
SELECT e.ename, d.deptno
FROM emp e, dept d
WHERE e.deptno = d.deptno;
**JOIN~ON절**
SELECT e.ename, d.deptno
FROM emp e JOIN dept d ON (e.deptno = d.deptno);
**USING절**
SELECT e.ename, d.deptno
FROM emp e JOIN dept d USING(deptno);

 
위의 where, join~on, using 예시는 모두 같은 결과를 도출해낸다.
= ⓵은 오류


43. 아래 두 SQL이 같은 결과를 출력할 때, 빈칸 ㉠에 들어갈 내용으로 가장 적절한 것은?
[SQL(1)]
SELECT       ENAME, DNAME
FROM          EMP, DEPT
ORDER BY   ENAME;

[SQL(2)]
SELECT       ENAME, DNAME
FROM          EMP ㉠ DEPT
ORDER BY   ENAME;
⓵ FULL OUTER JOIN
⓶ SELF JOIN
⓷ NATURAL JOIN
⓸ CROSS JOIN

 
FULL OUTER JOIN : 두 테이블 모두에서 일치하는 행과 일치하지 않는 행을 모두 포함하여 결과 반환
-> 일치하지 않는 행에는 NULL 값으로 반환하여 출력

--example
SELECT *
FROM emp e
   FULL OUTER JOIN dept d ON e.deptno = d.deptno
emp 테이블과 dept 테이블을 deptno 컬럼을 기준으로 FULL OUTER JOIN

 
SELF JOIN : JOIN의 대상이 자기 자신
-> 같은 테이블이 두번 나오기 때문에 꼭 alias(별칭)을 지정해줘야 한다.

---1 
SELECT e1.name AS Employee, e2.name AS Manager
FROM employees e1
  LEFT JOIN employees e2 ON e1.mgr = e2.id;
  
---2
SELECT e1.name AS Employee, e2.name AS Manager
FROM employees e1
  INNER JOIN employees e2 ON e1.mgr = e2.id;
SELF JOIN ( LEFT OUTER JOIN과 INNER JOIN의 차이 )

 
NATURAL JOIN : 두 테이블 간의 공통된 컬럼을 자동으로 찾아서 조인
-> 공통된 컬럼을 자동으로 찾기 때문에 ON절은 필요로 하지 않음

--example
SELECT *
FROM emp e
   NATURAL JOIN dept d
INNER JOIN과 비슷하다고 생각할 수 있다.
하지만, INNER JOIN의 경우 ON으로 조건을 명시해줘야 하고,
NATURAL JOIN은 공통된 컬럼을 자동으로 찾기 때문에 ON으로 조건을 명시해주지 않아도 된다.
deptno 컬럼을 자동으로 찾아 조인 (컬럼이 같기 때문)

 
CROSS JOIN : 한쪽 테이블의 모든 행과 다른 쪾 테이블의 모든 행을 조인시키는 기능
-> 전체 행 개수 : 두 테이블의 각 행의 개수를 곱한 수만큼 (M × N)

-- 명시적 CROSS JOIN 표현
SELECT * FROM 테이블1 
	CROSS JOIN 테이블2

-- 암시적 CROSS JOIN 표현
SELECT * FROM 테이블1, 테이블2

1) CROSS JOIN 이라고 명시를 해 주거나
2) 테이블 두 개를 콤마(,)로 걸어주고 조건절에 따로 명시하지 않으면 CROSS JOIN이 생성된다.

employees 테이블과 address 테이블 CROSS JOIN 한 결과

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


[SQL]
SELECT A.고객번호, A.고객명, B.단말기ID, B.단말기명, C.OSID, C.OS명
FROM 고객 A
     LEFT OUTER JOIN 단말기 B ON (A.고객번호 IN (11000, 12000) AND A.단말기ID = B.단말기ID)
     LEFT OUTER JOIN OS C ON (B.OSID = C.OSID)
ORDER BY A.고객번호;







 

FROM 고객 A 
     LEFT OUTER JOIN 단말기 B ON (A.고객번호 IN (11000, 12000) AND A.단말기ID = B.단말기ID)
     LEFT OUTER JOIN OS C ON (B.OSID = C.OSID)
고객 A와 단말기 B를 단말기ID 컬럼으로 연결하고,
A.고객번호가 11000 또는 12000인 컬럼 추출
 ** 고객 A가 기준 **
-> 고객 A 컬럼은 모두 출력, 조건에 맞지 않는 행은 NULL로 출력

단말기 B와 OS C를 OSID 컬럼으로 연결
 ** 단말기 B가 기준 **

SELECT A.고객번호, A.고객명, B.단말기ID, B.단말기명, C.OSID, C.OS명위 조건에 만족하는 행 출력
ORDER BY A.고객번호A.고객번호 기준으로 오름차순 정렬 (ASC는 생략 가능)

45. 아래 SQL에서 실행 결과가 같은 것은?
(가)
SELECT   A.ID, B.ID
FROM      TBL1 A
     FULL OUTER JOIN TBL2 B ON A.ID = B.ID

(나)
SELECT   A.ID, B.ID
FROM      TBL1 A
     LEFT OUTER JOIN TBL2 B ON A.ID = B.ID
UNION
SELECT   A.ID, B.ID
FROM      TBL1 A
     RIGHT OUTER JOIN TBL2 B ON A.ID = B.ID

(다)
SELECT   A.ID, B.ID
FROM      TBL1 A, TBL2 B
WHERE    A.ID = B.ID
UNION ALL
SELECT   A.ID, NULL
FROM      TBL1 A
WHERE    NOT EXISTS (SELECT 1 FROM TBL2 B WHERE A.ID = B.ID)
UNION ALL
SELECT   NULL, B.ID
FROM      TBL2 B
WHERE    NOT EXISTS (SELECT 1 FROM TBL1 A WHERE B.ID = A.ID)
⓵ (가), (나)
⓶ (가), (다)
⓷ (나), (다)
⓸ (가), (나), (다)

 

(가)
SELECT A.ID, B.ID
FROM TBL1 A
	FULL OUTER JOIN TBL2 B ON A.ID = B.ID

TBL1 A와 TBL2 B를 ID컬럼을 기준으로 FULL OUTER JOIN
-> 두 테이블 모두에서 일치하는 행과 일치하지 않는 행을 모두 포함하여 결과 반환
-> 일치하지 않는 행에는 NULL 값으로 반환하여 출력

(나)
SELECT A.ID, B.ID
FROM TBL1 A
	LEFT OUTER JOIN TBL2 B ON A.ID = B.ID
UNION
SELECT A.ID, B.ID
FROM TBL1 A
	RIGHT OUTER JOIN TBL2 B ON A.ID = B.ID

OUTER JOIN : 열을 추가하여 JOIN
UNION : 행을 추가하여 각 쿼리의 결과를 반환하는 합집합 (중복제거)

초록색 부분은 중복되었지만 UNION 한 결과를 보면 중복이 제거되어 나온 것을 알 수 있다.
두 개의 쿼리의 합집합으로 결과가 출력된다.

(다)
--1
SELECT A.ID, B.ID
FROM TBL1 A, TBL2 B
WHERE A.ID = B.ID
--2
UNION ALL
SELECT A.ID, NULL
FROM TBL1 A
WHERE NOT EXISTS (SELECT 1 FROM TBL2 B WHERE A.ID = B.ID)
--3
UNION ALL
SELECT NULL, B.ID
FROM TBL2 B
WHERE NOT EXISTS (SELECT 1 FROM TBL1 A WHERE B.ID = A.ID)

UNION ALL : 행을 추가하여 각 쿼리의 모든 결과를 합집합 (중복제거 안함)

NOT EXISTS (SELECT 1 FROM TBL2 B WHERE A.ID = B.ID)A.ID가 TBL2에 존재하는지 검사하는 서브쿼리
-> 존재하면 FALSE (A.ID = B.ID 제외하고 나머지 출력)
-> 존재하지 않으면 TRUE (A.ID 그대로 출력)
NOT EXISTS (SELECT 1 FROM TBL1 B WHERE B.ID = A.ID)B.ID가 TBL1에 존재하는지 검사하는 서브쿼리
-> 존재하면 FALSE (B.ID = A.ID 제외하고 나머지 출력)
-> 존재하지 않으면 TRUE (A.ID 그대로 출력)

46. 아래에서 EMP 테이블과 DEPT 테이블을 LEFT, FULL, RIGHT 외부조인(OUTER JOIN) 하면 생성되는 결과 건수로 가장 적절한 것은?
⓵ 3건, 5건, 4건
⓶ 4건, 5건, 3건
⓷ 3건, 4건, 4건
⓸ 3건, 4건, 5건

 

1)
emp e LEFT OUTER JOIN dept d ON e.C = d.C

(LEFT) EMP 테이블 전체 + 해당하는 조건에 맞는 DEPT 테이블의 행
-> 조건에 맞지 않는 행은 NULL 값으로 반환하여 출력

2)
emp e FULL OUTER JOIN dept d ON e.C = d.C

두 테이블 모두에서 일치하는 행과 일치하지 않는 행을 모두 포함하여 결과 반환
-> 일치하지 않는 행에는 NULL 값으로 반환하여 출력

3)
emp e RIGHT OUTER JOIN dept d ON e.C = d.C

(RIGHT) DEPT 테이블 전체 + 해당하는 조건에 맞는 EMP 테이블의 행
-> 조건에 맞지 않는 행은 NULL 값으로 반환하여 출력


47. DEPT와 EMP를 조인하되 사원이 없는 부서 정보도 같이 출력하고자 할 때, 아래 SQL의 빈칸 ㉠에 들어갈 내용으로 가장 적절한 것은?
SELECT E.ENAME, D.DEPTNO, D.DNAME
FROM DEPT D
     ㉠ EMP E ON D.DEPTNO = E.DEPTNO;
⓵ LEFT OUTER JOIN
⓶ RIGHT OUTER JOIN
⓷ FULL OUTER JOIN
⓸ INNER JOIN

 

  • 사원이 없는 부서정보 -> 사원의 값은 NULL, 부서정보의 값은 있다는 의미로 볼 수 있다.
    • DEPT 테이블 : 부서정보를 담고 있는 테이블
    • EMP 테이블 : 사원정보를 담고 있는 테이블

--> EMP E 의 값은 NULL을 가지고, DEPT D 의 값은 NULL을 가지지 않으려면 DEPT 테이블을 기준으로 OUTER JOIN
 
= LEFT OUTER JOIN


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



[SQL]
SELECT *
FROM TAB1 A 
     LEFT OUTER JOIN TAB2 B ON (A.C1 = B.C1 AND B.C2 BETWEEN 1 AND 3)






 

SELECT *
FROM TAB1 A 
     LEFT OUTER JOIN TAB2 B ON (A.C1 = B.C1 AND B.C2 BETWEEN 1 AND 3)
  • FROM : TAB1 전체 테이블을 가져오고, TAB1 테이블과 TAB2 테이블은 C1 컬럼으로 연결
    • 조건: B.C2의 값이 1과 3 사이어야한다.
  • SELECT : TAB1 컬럼 전체와 TAB2 컬럼 전체를 가져온다.
    • A.C1, A.C2, B.C1, B.C2

49. 아래의 오라클 SQL을 동일한 결과를 출력하는 ANSI 표준 구문으로 변경하고자 할 때 가장 적절한 SQL은?


[SQL]
SELECT       A.게시판ID, A.게시판명, COUNT(B.게시글ID) AS CNT
FROM          게시판 A, 게시글 B
WHERE       A.게시판ID = B.게시판ID(+)
    AND         B.삭제여부(+) = 'N'
    AND         A.사용여부 = 'Y'
GROUP BY  A.게시판ID, A.게시판명
ORDER BY   A.게시판ID;






 

  • (+) = : 해당 기호를 한 테이블에서 조건의 데이터가 없다면 NULL을 사용하라!
    • ex) WHERE emp.dept_id = dept.dept_id(+)
      : dept 테이블에서 dept_id가 emp 테이블의 dept_id 와 일치하는 것이 없다면 NULL을 사용하라
      => 즉, emp LEFT OUTER JOIN dept 와 같다는 것을 알 수 있다.
    • (+) 기호의 반대편 테이블은 전체 출력 되는 것!

 

예시 테이블
FROM 게시판 A, 게시글 B게시판 테이블의 별칭 A, 게시글 테이블의 별칭 B로 하고,
A 테이블과 B 테이블을 가져온다.
WHERE A.게시판ID = B.게시판ID(+)
    AND B.삭제여부(+) = 'N'
    AND A.사용여부 = 'Y'
<조건>
게시글 B의 게시판ID가 게시판 A의 게시판ID와 일치하는 것이 없다면 NULL 출력
-> 게시판 테이블 A 전체 출력
-> 게시판 A LEFT OUTER JOIN 게시글 B

게시글 B의 삭제여부가 N
게시글 B의 삭제여부가 N과 일치하지 않다면 B.삭제여부를 NULL로 출력

게시판 A의 사용여부가 Y



GROUP BY A.게시판ID, A.게시판명게시판 A의 게시판ID와 게시판 A의 게시판명을 기준으로 그룹화
SELECT
A.게시판ID, A.게시판명, COUNT(B.게시글ID) AS CNT
게시판 A의 게시판ID, 게시판명
게시글 B의 게시글ID의 NULL을 제외한 행의 수 (별칭: CNT)
ORDER BY A.게시판ID게시판 A의 게시판ID를 기준으로 오름차순 정렬



 

  1. 우선 문제의 SQL은 게시판 A LEFT OUTER JOIN 게시글 B 임을 알 수 있다.
    => ⓸ 제외 (게시판 A RIGHT OUTER JOIN 게시글 B 이기 때문에)
  2. A.게시판ID = B.게시판ID(+) AND B.삭제여부(+) = 'N'
    -> B의 게시판ID와 삭제여부는 값이 일치하지 않다면 NULL을 출력하는 것을 보아 해당 조건은 LEFT OUTER JOIN의 ON절에 해당하는 것을 알 수 있다.
  3. 결과적으로 FROM절과 WHERE절을 정리하면
    FROM절 - 게시판 A LEFT OUTER JOIN 게시글 B ON (A.게시판ID = B.게시판ID AND B.삭제여부 = 'N')
    WHERE절 - A.사용여부 = 'Y'

50. 아래에 대한 설명으로 가장 적절한 것은? (단, 칼럼의 타입은 NUMBER 이다.)
⓵ SELECT SUM(COL2) FROM TAB1 의 결과는 NULL이다.
⓶ SELECT SUM(COL1 + COL2 + COL3) FROM TAB1 의 결과는 185이다.
⓷ SELECT SUM(COL2 + COL3) FROM TAB1 의 결과는 90이다.
⓸ SELECT SUM(COL2) + SUM(COL3) FROM TBA1 의 결과는 90이다.

 

**SUM( ) 함수**
: NULL값을 제외하고 계산

SUM( ) 함수의 괄호 안에 연산자가 있다면 따로 컬럼을 빼주어 연산해주는 것이 헷갈리지 않게 연산할 수 있다.
-> 보통 SUM( )을 하면 세로로(컬럼) 연산하기 때문에 (이해를 더 쉽게 하기 위해서)
SUM(COL2)NULL값을 제외하고 20+70=90SUM(COL3)NULL값을 제외하고 20
SUM(COL2 + COL3)NULL 값을 제외하고 90SUM(COL1 + COL2 + COL3)NULL값을 제외하고 140

51. 아래에서 설명하는 서브쿼리의 종류로 가장 적절한 것은?
서브쿼리의 실행 결과로 여러 칼럼을 반환한다. 메인쿼리의 조건절에 여러 칼럼을 동시에 비교할 수 있다. 서브쿼리와 메인쿼리에서 비교하고자 하는 칼럼 개수와 칼럼의 위치가 동일해야 한다.
⓵ 단일 행(Single Row) 서브쿼리
⓶ 다중 칼럼(Multi Column) 서브쿼리
⓷ 다중 행(Multi Row) 서브쿼리
⓸ 단일 칼럼(Single Column) 서브쿼리

 

  • 서브쿼리 : 메인 쿼리 내에서 다른 쿼리를 포함하여 실행하는 쿼리
    • 반환 값에 따른 서브쿼리
      • 단일 행 서브쿼리 : 서브쿼리 결과 = 단일 행
        -> 단일 행 비교연산자 (=, <, >, <=, >=, <>)
      • 다중 행 서브쿼리 : 서브쿼리 결과 = 여러 행
        -> 다중 행 비교연산자 (IN, ALL, ANY, SOME, EXISTS)
      • 다중 칼럼 서브쿼리 : 서비쿼리 결과 = 여러 칼럼
        -> 메인쿼리의 조건절에 여러 칼럼을 동시에 비교 가능
        -> 비교하고자 하는 칼럼 개수와 칼럼의 위치가 동일해야 함
    • 위치에 따른 서브쿼리
      • 스칼라 서브쿼리 : SELECT절에 위치. 단일 값을 반환하는 서브쿼리 
        -> 단일 행, 단일 칼럼 반환
      • 인라인 뷰 : FROM절에 위치하는 서브쿼리
      • 상관 서브쿼리 : WHERE절에 위치. 주 쿼리의 칼럼을 참조하는 서브쿼리
        -> 단일 행, 다중 행 반환

52. SQL 실행 결과가 다른 하나는?

SELECT        COL1, SUM(COL2)
FROM           T1
GROUP BY   COL1
UNION ALL
SELECT        NULL, SUM(COL2)
FROM           T1
ORDER BY    1 ASC;


SELECT         COL1, SUM(COL2)
FROM            T1
GROUP BY    GROUPING SETS (COL1)
ORDER BY     1 ASC;


SELECT         COL1, SUM(COL2)
FROM            T1
GROUP BY    ROLLUP(COL1)
ORDER BY     1 ASC;


SELECT         COL1, SUM(COL2)
FROM            T1
GROUP BY    CUBE(COL1)
ORDER BY     1 ASC;

 

  • ROLLUP( ) : 그룹별 소계와 총계를 같이 계산, 기준 필드가 여러 개인 경우 콤마로 구분
    • 기준 필드가 2개일 때: 1차 기준 필드에 대한 소계를 계산 + 총계
  • CUBE( ) : 모든 기준 필드에 대한 소계
    • 기준 필드가 2개일 때 : 1차 기준 필드에 대한 소계를 계산 + 2차 기준 필드에 대한 소계 + 총계
  • GROUPING SET( ) : 그룹별 소계만 계산
    • 기준 필드가 2개일 때 : 1차 기준 필드에 대한 소계 + 2차 기준 필드에 대한 소계
예시 테이블

SELECT        COL1, SUM(COL2)
FROM           T1
GROUP BY   COL1
T1 테이블을 가져오고, COL1 값을 기준으로 그룹화한 후
COL1 과 SUM(COL2)를 가져온다.
SELECT        NULL, SUM(COL2)
FROM           T1
T1 테이블을 가져오고, NULL값과 SUM(COL2)값을 가져온다.
위의 결과를 "UNION ALL"한 후 값은 "ORDER BY 1 ASC"한 값은?

-> UNION ALL과 UNION의 차이:
    - UNION: 중복되는 값은 제거하여 결과 합집합 (DISTINCT)
    - UNION ALL: 중복되는 값 모두 포함하여 결과 합집합 (DISTINCT 하지 않음)

 


SELECT         COL1, SUM(COL2)
FROM            T1
GROUP BY    GROUPING SETS (COL1)
ORDER BY     1 ASC;
T1 테이블을 가져오고 COL1을 기준으로 소계를 낸다.
COL1과 SUM(COL2)의 값을 가져오고 COL1을 기준으로 오름차순 정렬한다.

-> GROUPING SET과 CUBE, ROLLUP의 차이:
   - GROUPING SET: 지정 필드에 대한 소계만 낸다.
   - CUBE, ROLLUP: 지정 필드에 대한 소계와 총계를 같이 낸다.