본문 바로가기
SQLD/SQLD 오답노트

오답노트 (문39 ~ 문64) (2-1 과목 [하])

by moca7 2023. 11. 14.

 

ㅁ 문39. 다음 중 결과가 다른 sql 문장은?

 

2014년12월00시에 가입해서 2015년 1월에 서비스가 끝나는 서비스 아이디를 찾는 문제. 

 

= 답39.

WHERE '201501' = TO_CHAR(SVC_END_DATE, 'YYYYMM') <- TO_CHAR은 2015년 1월임.

WHERE TO_DATE('201501'. 'YYYYMM') <- TO_DATE는 연월만 지정하고 일 비우면 자동으로 해동월 1일로 세팅됨.

 

= where절에 조건1 and 조건2 있으면 조건1과 2 다 만족해야함.

 

ㅁ 문40. 내장함수에 대한 설명 중에서 옳은것을 모두 고른 것은?

 

(가) 함수의 입력 행수에 따라 단일행 함수와 다중행 함수로 구분할 수 있다.

(나) 단일행 함수는 select, where, order by, update의 set 절에 사용이 가능하다.

(다) 1:m관계의 두 테이블을 조인할 경우 m 쪽에 다중행이 출력되므로 단일행 함수는 사용할 수 없다.

(라) 단일행 함수는 다중행 함수와 다르게 여러 개의 인수가 입력되어도 단일값만을 반환한다.

 

= 답40.  (가), (나).

(다) <- 1:M 조인이라 하더라도 M쪽에서 출력된 행이 하나씩 단일행 함수의 입력값으로 사용되므로 사용할 수 있다.

(라) <- 다중행 함수도 단일행 함수와 동일하게 단일 값만을 반환함.

 

ㅁ 문41. 아래와 같은 2 건의 데이터 상황에서 SQL의 수행결과로 가장 적절한 것은? (단, 이해를 돕기 위해 아래 화살표는 줄바꿈을 의미 -> 실제 저장값이 아님, CHR(10):ASCII 값 -> 줄바꿈을 의미)

 

[TAB1]

ROWNUM      C1       

---------------------------------

     1                  A

                       아래화살표

                        A

----------------------------

      2                 B

                       아래화살표

                         B

                       아래화살표

                        B

 

[SQL]

SELECT SUM(CC)

FROM ( SELECT(LENGTH(C1) - LENGTH(REPLACE(C1, CHR(10))) + 1) CC

              FROM TAB1)

 

= C1의 값이 'A 엔터 A'(자리수 3)와 'B 엔터 B 엔터 B'(자리수 5)인 거임. 아래화살표는 도우미로 별개로 표시한거고.

= CHR(10)은 줄바꿈(엔터)을 의미함.

= REPLACE는 문자열을 치환하는 함수다. REPLACE(C1, CHR(10))은 줄바꿈(엔터) 제거를 의미함.

= 고로 LENGTH(C1)은 3, 5고 LENGTH(REPLACE(C1, CHR(10))은 2, 3을 의미함. (3-1)과 (5-2)를 하고 각각의 행에 1을 더함. 그리고 총합임. 총합하고 +1이 아니고. 고로 답은 5.

 

ㅁ 문42. 오라클 환경에서 날짜형 데이터를 다룰 경우, 아래 SQL 결과로 가장 적절한 것은?

 

SELECT TO_CHAR(TO_DATE('2015.01.10 10', 'YYYY.MM.DD HH24') + 1/24/(60/10), 

'YYYY.MM.DD HH24:MI:SS') FROM DUAL

 

= 답 42. 2015.01.10 10:10:00

= 오라클에서 날짜 연산은 숫자 연산과 같음. 특정 날짜에 1을 더하면 하루를 더한 결과와 같으므로 1/24/60 = 1분을 의미한다. 1/24/(60/10) = 10분이다. 

 

ㅁ 문43. 아래의 SEARCHED_CASE_EXPRESSION SQL문장이다. 이 때 사용된 SEARCHED_CASE_EXPRESSION은 SIMPLE_CASE_EXPRESSION을 이용해 똑같은 기능을 표현할 수 있다. (ㄱ)에 들어갈 표현은? (스칼라 서브쿼리는 제외함)

 

[ SEARCHED_CASE_EXPRESSION]

SELECT LOC, CASE WHEN LOC = 'NEW YORK' THEN 'EAST' ELSE 'ETC' END AS AREA FROM DEPT;

 

[ SIMPLE_CASE_EXPRESSION]

SELECT LOC, CASE (ㄱ) ELSE 'ETC' END AS AREA FROM DEPT;

 

= 답43. LOC WHEN 'NEW YORK' THEN 'EAST'

= SIMPLE CASE는 CASE하고 칼럼나오고 WHEN 'A' THEN 'B' 인데,

SEARCHED CASE는 CASE하고 WHEN 칼럼='A' THEN 'B'이다.

 

ㅁ 문45. 다음 중 아래 TAB1을 보고 각 SQL 실행 결과를 가장 올바르게 설명한 것을 고르시오.

 

[TAB1]

COL1        COL2

-----------------------

a               NULLb                 ''c                 3d                 4e                 3

 

(1) SELECT COL2 FROM TAB1 WHERE COL1 = 'b';      -> 실행 결과가 없다.(공집합)(2) SELECT ISNULL(COL2, 'X') FROM TAB1 WHERE COL1 ='a';              -> 실행 결과로 'X'를 반환한다.(3) SELECT COUNT(COL1) FROM TAB1 WHERE COL2 = NULL;             -> 실행 결과는 1이다.

(3) SELECT COUNT(COL2) FROM TAB1 WHERE COL2 IN ('b', 'c');           -> 실행 결과는 1이다.

 

= 답45. (2). NULL이 널로 인정됐네. 오라클, SQL Server 다 null이라 써있으면 null이네. 

 

= 일단 이 문제는 ORACLE 문제가 아니라 MYSQL 문제임. 근거1은 ISNULL함수, 근거2는 테이블의 값이 NULL이 아닌 ''으로 표현되어 있음. 오라클이었다면 ''과 NULL이 같기 때문에 NULL로 표현됐을 것. 

= MYSQL은 ''(빈값)을 ''(빈값) 그대로 인정함. 

= ''은 빈문자. ' '은 공백문자(1칸). NULL은 지정되지 않은 값. 공집합은 아무것도 없는 것.

공집합은 집합의 개념으로 레코드가 0건인거고, NULL, ''(빈값), ' '(공백)과는 다르게 접근해야 함.

 

= (1)은 실행결과로 ''이 나옴. (4)는 2가 나옴.

= (3) 

 - 'NULL'로 바꿔주면 1 나온다. 

 - IS NULL로 바꿔주면 1 나옴.

 

 - 오류가 나오는게 아니고, 조건을 만족할 수 없어 거짓이 됨. NULL과의 비교연산은 FALSE를 리턴한다. 오류 아님. 이걸 카운트하면 만족하는 행이 없어 0이 나옴. 

 - COUNT(어쩌구) FROM 어쩌구 WHERE 1=2. 카운트 집계함수는 조건절이 거짓일때 0을 반환함. 

 

 - WHERE 1=2는 답이 FALSE는 아니고 공집합이다. 조건에 맞는 데이터가 한 건도 없는 경우를 공집합이라 하고 NULL과는 다르다. EX) ENAME='JSC'인데 JSC라는 사람이 아예 없음.

 - 여기에 NVL(공집합, 9999) 해도 여전히 공집합 나옴. NVL과 ISNULL은 NULL 값을 다른 값으로 바꾸는거지 공집합을 대상으로 하지 않음.

 - 집계함수와 스칼라 서브쿼리 MAX(MGR)같은 경우는 인수의 결과 값이 공집합인 경우에도 NULL을 출력함.

 

ㅁ 문 47. 

 

= 분모가 0이 들어가는 경우 연산 자체가 에러를 발생하며 원하는 결과를 얻을 수 없다.

= ' 0/300 = 0 '이다. ' 5000/0 '은 에러다. 

 

ㅁ 문48. 아래와 같은 데이터 상황에서 sql의 수행 결과로 가장 적절한 것은?

 

[TAB1]

C1    C2     C3

--------------------

1        2         3

          2         3

                     3

 

SELECT SUM(COALESCE(C1, C2, C3)) FROM TAB1

 

= 답48. 답은 6. 

= 근데 이게 열로서 1+2+3이냐 행으로서 1+2+3이냐. 후자다. COALESCE 함수는 각 '행'에서 첫번째로 NULL이 아닌 값을 반환함.

 

ㅁ 문50. 아래 각각 3개의 SQL 수행 결과로 가장 적절한 것은?

 

SELECT AVG(COL3) FROM TAB_A;

SELECT AVG(COL3) FROM TAB_A WHERE COL1 >0;

SELECT AVG(COL3) FROM TAB_A WHERE COL1 IS NOT NULL;

 

[TAB_A]

COL1           COL2               COL3

------------------------------------------------

30                   NULL                 20

NULL                  40                  0

0                         10               NULL

 

= 답50. 10, 20, 20. 널 값은 집계함수에서 제외됨.

 

ㅁ 문51. 어느 기업의 직원 테이블(EMP)이 직급(GRADE) 별로 사원 500명, 대리 100명, 과장 30명, 차장10명, 부장5명, 직급이 정해지지 않은(NULL) 사람 25명으로 구성되어 있을 때, 다음 SQL문을 1~3까지 순차적으로 실행한 결과 건수를 순서대로 나열한 것은?

 

SQL1) SELECT COUNT(GRADE) FROM EMP;

SQL2) SELECT GRADE FROM EMP WHERE GRADE IN ('차장', '부장', '널');

SQL3) SELECT GRADE, COUNT(*) FROM EMP GROUP BY GRADE;

 

= 답 51. 625, 15, 6

= '널'이 텍스트로 입력된 데이터는 없다. 정의되지 않은 미지의 값인 NULL과 '널' 텍스트 데이터는 다르다. 

또한 GRADE IN ('차장', '부장', NULL)로 변경하여도 실제 NULL 데이터는 출력되지 않음. NULL과의 비교는 오직 IS NULL, IS NOT NULL만 가능.

= COUNT(*)로 전부 출력하고 GROUP BY하면 NULL도 하나의 그룹으로 나옴.

 

ㅁ 문52. 어느 회사의 광고에 대한 데이터 모델이다. 다음 중 광고매체 ID별 최초로 게시한 광고명과 광고시작일자를 출력하기 위하여 아래 (ㄱ)에 들어갈 SQL로 옳은 것은?

 

[광고]                                               [광고게시]                                          [광고매체]

광고ID                                            광고게시번호                                       광고매체ID

---------------                                   -----------------------                                  -------------------

광고명                                             광고ID (FK)                                         광고매체명

                                                        광고매체ID (FK)

                                                        광고시작일자

                                                        광고종료일자

 

[SQL]

SELECT C.광고매체명, B.광고명, A.광고시작일자

FROM 광고게시 A, 광고 B, 광고매체 C,

            ( ㄱ ) D

WHERE A.광고시작일자 = D.광고시작일자

AND A.광고매체ID = D.광고매체ID

AND A.광고ID = B.광고ID

AND A.광고매체ID = C.광고매체ID

ORDER BY C.광고매체명;

 

= 답52. 

SELECT 광고매체ID, MIN(광고시작일자) AS 광고시작일자

FROM 광고게시 

GROUP BY 광고매체ID

= 위에서 FROM 다음에 WHERE D.광고매체ID = C.광고매체ID 들어가면 틀린답. 이건 연관서브쿼리인데, 인라인 뷰에서 못 쓰고 WHERE절에서 써야함.

= 내가 내걸 쓰는거니까(조인아님) 조인 필요 없음.

 

ㅁ 문53. 다음 중 오류가 발생하는 SQL 문장은?

 

(1) SELECT 회원ID, SUM(주문금액) AS 합계

FROM 주문 GROUP BY 회원ID

HAVING COUNT(*) >1;

- WHERE 절은 없어도 됨.

 

(2) SELECT SUM(주문금액) AS 합계

FROM 주문 HAVING AVG(주문금액) > 100;

- WHERE 절뿐 아니라 GROUP BY절 없이 HAVING절에 집계함수 사용. 집계함수를 WHERE절엔 못쓰고 HAVING, SELECT, ORDER BY절에만 쓸 수 있으니 그런듯.

- 그룹바이 절 없이 그냥 SUM한거면 모든 데이터를 대상으로 SUM했다는 거. (결과 1건)

- 그룹바이절이 없어도 해빙절에 집계함수를 쓰기도 함. 

 

(3) SELECT 메뉴ID, 사용유형코드, COUNT(*) AS CNT

FROM 시스템사용이력

WHERE 사용일시 BETWEEN SYSDATE-1 AND SYSDATE

GROUP BY 메뉴ID, 사용유형코드

HAVING 메뉴ID = 3 AND 사용유형코드 =100;

- GROUP BY로 그룹핑된 칼럼에 대해 HAVING 조건절을 사용할 경우 집계된 칼럼의 FILTER조건으로 사용할 수 있다. 이런 경우 HAVING절에 집계함수가 없이도 사용할 수 있다.

- WHERE절과 HAVING절 둘다 써도 됨. 해빙절에 집계함수가 아닌 일반함수 써도 됨. 해빙절의 조건을 집계함수 아니니까 WHERE절에 다 써도 됨.

 

(4) SELECT 메뉴ID, 사용유형코드, AVG(COUNT(*)) AS AVGCNT

FROM 시스템사용이력 GROUP BY 메뉴ID, 사용유형코드;

= 중첩된 그룹함수의 경우 최종 결과값은 1건이 될 수 밖에 없기에 GROUP BY절에 기술된 메뉴ID와 사용유형코드는 SELECT절에 기술될 수 없다.

- 중첩집계여서 오류. 중첩집계는 집계한 결과를 다시 집계하는것. COUNT로 집계한 결과를 AVG로 또 집계하고 있음. 

중첩집계를 쓸 때는 SELECT절에 중첩집계만 나와야함. 일반 칼럼은 안되고.  

(그룹별로 쭉 나오고, 옆에는 1건의 데이터만 나옴. 마치 그 부서에 전체 집계인것처럼 나와서 안된다?)

 

ㅁ 문54. 다음 중 아래와 같은 테이블 A에 대해서 SQL을 수행하였을 때의 결과로 가장 적절한 것은?

 

CREATE TABLE A (

가 VARCHAR(5) PRIMARY KEY,

나 VARCHAR(5) NOT NULL,

다 INT NOT NULL );

 

[테이블 A]

가                           나                             다

------------------------------------------------------------------

001                        A001                         100

002                        A001                         200

003                        A002                         100

004                        A002                         200

005                        A002                         200

006                        A003                         100

007                        A003                         200

008                        A003                         100

009                        A003                         200

010                        A004                         200

 

[SQL]

SELECT MAX(가) AS 가, 나, SUM(다) AS 다

FROM A GROUP BY 나

HAVING COUNT(*)>1 ORDER BY 다 DESC;

 

= 답54. 

가                           나                             다

------------------------------------------------------------------

009                        A003                         600

005                        A002                         500

002                        A001                         300

(010                       A004                          200)   - COUNT(*)가 0이 아닌 1보다 큰거니까 A004는 조건에 걸림!

 

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

 

[TBL]

ID

-------

100

100

200

200

200

999

999

999

 

SELECT ID FROM TBL 

GROUP BY ID HAVING COUNT(*)=2

ORDER BY (CASE WHEN ID=999 THEN 0 ELSE ID END)

 

= 답55. 

ID

----

999

100

= ORDER BY 다음에 칼럼이나 표현식. 그래서 CASE 조건식도 되나봄. 정렬시에만 저렇게 계산.

 

ㅁ 문 56. 다음 SQL 중 오류가 발생하는 것은?

 

(1) SELECT 지역, SUM(매출금액) AS 매출금액

FROM 지역별매출

GROUP BY 지역

ORDER BY 매출금액 DESC;

 

(2) SELECT 지역, 매출금액

FROM 지역별매출

ORDER BY 년 ASC;

 

(3) SELECT 지역, SUM(매출금액) AS 매출금액

FROM 지역별매출

GROUP BY 지역

ORDER BY 년 DESC;

 

(4) SELECT 지역, SUM(매출금액) AS 매출금액

FROM 지역별매출

GROUP BY 지역

HAVING SUM(매출금액) > 1000

ORDER BY COUNT(*) ASC;

 

= (2) SQL 실행 순서에 의하면 SELECT 절 이후에 ORDER BY 절이 수행되기 때문에 SELECT 절에 기술되지 않는 '년' 칼럼으로 정렬하는 것은 논리적으로 맞지 않다. 그러나 오라클은 행기반 DATABASE이기 때문에 SELECT절에 기술되지 않은 칼럼으로도 정렬할 수 있다. 

단, FROM절에 인라인 뷰가 사용된 경우에는 ORDER BY절에서 SELECT 절에 기술되지 않은 칼럼으로 정렬할 수 없다.

인라인 뷰가 사용되면 더 이상 SELECT절 외 칼럼을 쓸 수 없다.

= (3) GROUP BY를 사용할 경우 GROUP BY 표현식이 아닌 값은 기술될 수 없다.

 - 의미적으로 생각했을 때, 지역당 연도가 여러 해일텐데 년으로 정렬하는게 이상함.

= (4) GROUP BY 표현식이기에 가능하다. <- 그룹별로 묶은 다음 행들의 정렬 순서를 그룹별 COUNT(*) 순서로 하는듯. ORDER BY 다음 칼럼도 되고 표현식도 되니까. 

 

= (2)와 (3)이 GROUP BY만 빼고 같음. 차이가 무엇이냐. 

ORDER BY에는 원래 SELECT절에 해당 칼럼이 없어도 테이블에 해당 칼럼이 있다면 그 칼럼을 쓸 수 있음.

그러나 DISTINCT나 GROUP BY처럼 데이터를 집약할 때는 SELECT절에 있는 칼럼만 쓸 수 있음.

= ORDERY BY절은 SQL문장으로 조회된 데이터들을 / 특정 칼럼을 기준으로 정렬하는데 사용함.

 

ㅁ 문58. 

 

SELECT ID, AMT FROM TBL

ORDER BY (CASE WHEN ID = 'A' THEN 1 ELSE 2 END), AMT DESC

 

= 답58. 이거 CASE조건식 내림차순하고 같으면 AMT 내림차순 이게 아니고,

CASE조건식 오름차순 하고 같으면 AMT 내림차순임.

 

ㅁ 문63. 

 

- 일반적으로 JOIN은 PK와 FK 값의 연관성에 의해 성립된다.

- EQUI JOIN은 JOIN에 관여하는 테이블 간의 칼럼 값들이 정확하게 일치하는 경우에 사용되는 방법이다.

- EQUI JOIN은 '=' 연산자에 의해서만 수행되며, 그 이외의 비교 연산자를 사용하는 경우에는 모두 Non EQUI JOIN이다.

- 대부분 Non EQUI JOIN을 수행할 수 있지만, 때로는 설계상의 이유로 수행이 불가능한 경우도 있다. 

 

ㅁ 문64. 다음 SQL의 실행 결과로 맞는 것은?

 

[EMP_TBL]                                      [RULE_TBL]

EMPNO          ENMAE                    RULE_NO          RULE

------------        ------------                   ---------------        ----------

1000               SMITH                        1                        S%

1050               ALLEN                        2                       %T%

1100               SCOTT

 

[SQL]

SELECT COUNT(*) CNT

FROM EMP_TBL A, RULE_TBL B

WHERE A.ENAME LIKE B.RULE

 

= 답64. 4. 

- 2가 아님. SMITH와 SCOTT 한명씩에게 RULE_NO가 1인행과 2인행 2개씩 생김.

 

'SQLD > SQLD 오답노트' 카테고리의 다른 글

오답노트 (문1 ~ 문38) (2-1 과목 [상])  (1) 2023.11.14
오답노트 (문1 ~ 문52) (1과목)  (1) 2023.11.12