SQLD 시험 10일 공부 과정

김호정's avatar
Dec 07, 2024
SQLD 시험 10일 공부 과정
 

공부 순서

 
  1. 먼저 SQLD 기출문제집 (SQL 자격검정 실전문제) 을 준비.
 
  1. ‘1과목 데이터 모델링의 이해’ (총 50문제)
    1. 1과목부터 먼저 풀었는데 처음보는 개념이 많았다. 대부분 이론문제였는데
      문제를 맞추는 것 보다 ‘이런 내용이 있고 이런 문제가 나오네’ 하고 파악하는 것을 목표로
      문제와 보기를 쭉 훑어보면서 풀었다.
       
  1. ‘2과목 SQL 기본 및 활용’ (총 126문제)
    1. 1과목을 다 풀고 곧바로 2과목을 풀기 시작했는데 개념을 모르면 아예 풀 수 없는 문제가 많았다.
      (집합연산자, Rank, Rollup, Grouping set 등)
      그래서 이때부터 개념공부를 병행했다.
       
  1. 아래 2가지 개념서가 가장 유명한 것 같았다.
SQLD 모든 것
SQLD 모든 것
유선배 SQL 개발자 과외노트
유선배 SQL 개발자 과외노트
 
개념정리가 필요하긴 하지만 책을 보면서 공부하기엔 시간이 없을거 같아
개념 정리된 영상 없나 찾아보다가 홍쌤의 데이터랩 채널을 찾았다.
 
홍쌤의 데이터랩 유튜브 채널
홍쌤의 데이터랩 유튜브 채널
 
 
notion image
 
올해 개정된 부분을 반영한 개념정리 영상이 올라와 있어서
1과목(총 1강), 2과목(총 3강) + 특강(NULL, 서브쿼리 등) + 기출문제 풀이 1회차
이렇게 본 것 같다. 약 10시간 분량의 강의인데 스카 가서도 듣고
이동할 때 지하철에서도 듣고 틈날때마다 들은 것 같다.
무료이지만 정리된 핵심 요약의 퀄리티가 매우 좋고, 선생님 강의 전달력도 좋다.
개념정리는 위 채널의 영상만 봐도 충분하다고 생각한다.
(노랭이 문제집만으로 부족한 사람은 홍쌤 사이트에서 추가 기출문제+풀이 구매가 가능하다.
고득점을 목표로 한다면 구매해서 풀어봐도 좋을 거 같다.)
 
  1. 노트 및 노션 정리
→ 강의 보면서 좀 헷갈리는 내용이나 노랭이 문제에서 봤던 개념이 있으면 캡쳐해서 정리했다.
 
[ 1과목 개념 캡쳐정리 ]
😁
SQLD 1과목 개념정리
 
[ 2과목 ]
2과목 부터는 모르는 내용 투성이라 캡쳐는 따로 안하고 쭉 영상을 집중해서 봤다.
 
notion image
 
강의 들으면서 공책에 그려보면서 이해하려고 했다.
 
답안지를 봐도 이해가 안되는 문제들이 있었는데
 
notion image
 
그럴 땐 유튜브, 구글에 문제풀이를 검색해서 찾아보거나 챗지피티한테 물어봤다.
 
또 쿼리가 복잡하거나 매우 긴 문제들이 있었는데 그럴땐
 
  1. 테이블 과 데이터를 직접 생성해서 연습해보았다.
 
실습을 위한 테이블 생성
실습을 위한 테이블 생성
 

연습한 쿼리들

select 24*123 from dual; select deptno, job, decode(deptno, 10, decode(job, 'CLERK', 'A', 'B'), 'c') AS RESULT from emp; // 오라클은 소문자 대문분 SELECT * FROM EMP WHERE ENAME = 'smith'; select empno, ename, sal from emp where sal >=1500; select empno, ename, sal, comm from emp where comm is null; select empno, ename, sal, comm, deptno from emp where deptno = 10 AND sal >= 2000 OR empno = 7782; select deptno, max(sal), avg(sal) from emp group by deptno having avg(sal) > 1000; select deptno, sum(sal) from emp where sal > 2000 group by deptno; // 그룹함수를 사용해서 조건을 주고싶으면 having 절에 주어야 한다. select deptno, sum(sal) from emp group by deptno having sum(sal) > 9000; // 그룹함수는 허가되지 않습니다. where 절에는 그룹함수를 사용할 수 없다. Select Deptno, Sum(Sal) From Emp Where Sum(Sal) > 9000 Group By Deptno; // 테이블 추가 create table t1 ( no number(1) not null, name varchar2(1), constraint t1_pk primary key (no) ); create table t2 ( no number(1) not null, name varchar2(1), constraint t2_pk primary key (no) ); drop table t1; drop table t2; create table t1 ( no number(1), name varchar2(1) ); create table t2 ( no number(1), name varchar2(1) ); insert into t1 values (1, 'A'); insert into t1 values (2, 'B'); insert into t1 values (3, 'C'); insert into t1 values (NULL, 'D'); select * from t1; insert into t2 values (1, 'A'); insert into t2 values (1, 'B'); insert into t2 values (2, 'C'); insert into t2 values (NULL, 'D'); select * from t2; // equi 조인 (등가 조인) select t1.no, t2.no, t1.name, t2.name from t1, t2 where t1.no = t2.no; // 별칭 버전 // 일반 조건은 조인 조건 뒤에 AND로 붙여서 줄 수 있다. // SQL SERVER와 다르게 ORACLE은 조인 조건을 ON절이 아닌 WHERE절에 준다. select 티원.no, 티투.no, 티원.name, 티투.name from t1 티원, t2 티투 where 티원.no = 티투.no AND 티원.no >=2; // 부서 테이블 추가 CREATE TABLE DEPT ( DEPTNO NUMBER(2) NOT NULL, DNAME VARCHAR2(10), LOC VARCHAR2(20) ); INSERT INTO DEPT VALUES (10, 'ACCOUNTING', 'NEW YORK'); INSERT INTO DEPT VALUES (20, 'RESEARCH', 'DALLAS'); INSERT INTO DEPT VALUES (30, 'SALES', 'CHICAGO'); INSERT INTO DEPT VALUES (40, 'OPERATIONS', 'BOSTON'); // EMP 테이블과 DEPT 테이블을 사용하여 각 직원의 이름과 부서명을 함께 출력 SELECT EMP.ENAME, EMP.DEPTNO, DEPT.DNAME FROM EMP, DEPT WHERE EMP.DEPTNO = DEPT.DEPTNO; // 연결 조건을 쓰지 않으면 크로스 조인이 발생 SELECT EMP.ENAME, EMP.DEPTNO, DEPT.DNAME FROM EMP, DEPT; // SALGRADE TABLE 추가 CREATE TABLE SALGRADE ( GRADE NUMBER(1) NOT NULL, LOSAL NUMBER(4), HISAL NUMBER(4) ); INSERT INTO SALGRADE VALUES (1, 700, 1200); INSERT INTO SALGRADE VALUES (2, 1201, 1400); INSERT INTO SALGRADE VALUES (3, 1401, 2000); INSERT INTO SALGRADE VALUES (4, 2001, 3000); INSERT INTO SALGRADE VALUES (5, 3001, 9999); // NON EQUI JOIN 연습 - BETWEEN AND SELECT E.ENAME, E.SAL, S.GRADE FROM EMP E, SALGRADE S WHERE E.SAL BETWEEN S.LOSAL AND S.HISAL; // SELF JOIN 연습 - 매니저보다 급여가 많은 직원 출력 SELECT E1.EMPNO, E1.ENAME, E1.SAL, E2.EMPNO, E2.ENAME, E2.SAL FROM EMP E1, EMP E2 WHERE E1.MGR = E2.EMPNO // 셀프 조인 조건 AND E1.SAL > E2.SAL; // 조인 후에 필터링 하는 조건 // 표준 조인 // 표준 조인 중에서 ANSI 표준으로 작성한 INNER JOIN SELECT EMP.ENAME, DEPT.DNAME FROM EMP INNER JOIN DEPT ON (EMP.DEPTNO = DEPT.DEPTNO) ORDER BY DEPT.DNAME ; // 조인할 컬럼명이 같을 경우 ON절 대신 USING을 사용할 수도 있다. SELECT EMP.ENAME, DEPT.DNAME FROM EMP JOIN DEPT USING (DEPTNO); // NATURAL JOIN SELECT * FROM T1 NATURAL JOIN T2; // NO 와 NAME이 둘다 동일한 경우만 출력됨 SELECT EMP.ENAME, DEPT.DNAME FROM EMP NATURAL JOIN DEPT; // OUTER JOIN 연습 CREATE TABLE PROFESSOR ( PROFNO NUMBER(4), NAME VARCHAR2(20), POSITION VARCHAR2(20), DEPTNO NUMBER(3) ); CREATE TABLE STUDENT2 ( STUDNO NUMBER(4), NAME VARCHAR2(20), GRADE NUMBER(1), TEL VARCHAR2(20), PROFNO NUMBER(4) ); DROP TABLE STUDENT2; DROP TABLE PROFESSOR; INSERT INTO STUDENT2 VALUES (5001, '강성근', 4, '010-1234-1234', 1001); INSERT INTO STUDENT2 VALUES (5002, '고대영', 4, '010-1234-1234', 2001); INSERT INTO STUDENT2 VALUES (5003, '권정현', 4, '010-1234-1234', 3002); INSERT INTO STUDENT2 VALUES (5004, '김정일', 4, '010-1234-1234', 4001); INSERT INTO STUDENT2 VALUES (5005, '김재현', 4, '010-1234-1234', 4003); INSERT INTO STUDENT2 VALUES (8001, '이유나', 1, '010-1234-1234', NULL); INSERT INTO STUDENT2 VALUES (8002, '이민정', 1, '010-1234-1234', NULL); INSERT INTO STUDENT2 VALUES (8003, '전영훈', 1, '010-1234-1234', NULL); INSERT INTO STUDENT2 VALUES (8004, '허민기', 1, '010-1234-1234', NULL); INSERT INTO PROFESSOR VALUES (1001, '강경연', '정교수', 101); INSERT INTO PROFESSOR VALUES (1002, '경윤영', '조교수', 101); INSERT INTO PROFESSOR VALUES (1003, '김다훈', '전임강사', 101); INSERT INTO PROFESSOR VALUES (2001, '노경우', '전임강사', 102); INSERT INTO PROFESSOR VALUES (2002, '이용준', '조교수', 102); INSERT INTO PROFESSOR VALUES (2003, '장요한', '정교수', 102); INSERT INTO PROFESSOR VALUES (3001, '전홍범', '정교수', 103); INSERT INTO PROFESSOR VALUES (3002, '정성용', '조교수', 103); INSERT INTO PROFESSOR VALUES (3003, '백승윤', '전임강사', 103); INSERT INTO PROFESSOR VALUES (4001, '한병두', '정교수', 201); INSERT INTO PROFESSOR VALUES (4002, '현기숙', '조교수', 201); INSERT INTO PROFESSOR VALUES (4003, '오하영', '조교수', 202); INSERT INTO PROFESSOR VALUES (4004, '김만중', '전임강사', 202); // LEFT OUTER JOIN 예제 // STUDENT2 테이블과 PROFESSOR 테이블을 조인하여 // 1, 4학년 학생들의 이름, 학년, 지도교수이름 출력 SELECT S.NAME, S.GRADE, P.NAME FROM STUDENT2 S, PROFESSOR P WHERE S.PROFNO = p.PROFNO AND (S.GRADE = 1 OR S.GRADE = 4); // 괄호 안쓰면 카타시안 곱 발생 // 위처럼 하면 오라클 기본 조인인 INNER JOIN으로 출력됨 // 오라클에서 LEFT OUTER JOIN 사용시 SELECT S.NAME, S.GRADE, P.NAME FROM STUDENT2 S, PROFESSOR P WHERE S.PROFNO = P.PROFNO(+) AND (S.GRADE = 1 OR S.GRADE = 4); // OR 조건 대신 IN 을 사용할 수도 있다. SELECT * FROM STUDENT2 S, PROFESSOR P WHERE S.PROFNO = P.PROFNO(+) AND S.GRADE IN (1,4); // SQL SERVER에서 LEFT OUTER JOIN 사용시 SELECT S.NAME, S.GRADE, P.NAME FROM STUDENT2 S LEFT OUTER JOIN PROFESSOR P ON S.PROFNO = P.PROFNO WHERE S.GRADE = 1 OR S.GRADE = 4; // ANSI 표준 (IN 사용 버전) SELECT S.NAME AS 학생명, S.GRADE, P.NAME AS 교수명 FROM STUDENT2 S LEFT OUTER JOIN PROFESSOR P ON S.PROFNO = P.PROFNO WHERE S.GRADE IN (1,4); // PIVOT 연습 CREATE TABLE UNSTACK_TEST ( 년도 NUMBER(4), 성별 VARCHAR2(10), 지역 VARCHAR2(10), 구매량 NUMBER(1) ); INSERT INTO UNSTACK_TEST VALUES (2008, '남자', '서울', 1); INSERT INTO UNSTACK_TEST VALUES (2008, '남자', '경기', 2); INSERT INTO UNSTACK_TEST VALUES (2008, '여자', '서울', 3); INSERT INTO UNSTACK_TEST VALUES (2008, '여자', '경기', 4); INSERT INTO UNSTACK_TEST VALUES (2009, '남자', '서울', 5); INSERT INTO UNSTACK_TEST VALUES (2009, '남자', '경기', 6); INSERT INTO UNSTACK_TEST VALUES (2009, '여자', '서울', 7); INSERT INTO UNSTACK_TEST VALUES (2009, '여자', '경기', 8); // 성별, 연도별 구매량 총 합을 표한하는 교차표 작성 SELECT * FROM (SELECT 성별,년도,구매량 FROM UNSTACK_TEST) PIVOT(SUM(구매량) FOR 년도 IN(2008,2009)); // WIDE 데이터 형식으로 테이블 생성 CREATE TABLE TT5 ( MONTH NUMBER(2), 월 NUMBER(2), 화 NUMBER(2), 수 NUMBER(2), 목 NUMBER(2), 금 NUMBER(2), 토 NUMBER(2), 일 NUMBER(2) ); INSERT INTO TT5 VALUES (01, 10, 20, 30, 40, 45, 35, 60 ); INSERT INTO TT5 VALUES (02, 39, 45, 75, 34, 65, 45, 33 ); INSERT INTO TT5 VALUES (03, 13, 24, 67, 43, 45, 34, 56 ); INSERT INTO TT5 VALUES (04, 34, 50, 34, 22, 24, 43, 44 ); SELECT * FROM TT5; // UNPIVOT 연습 // 위의 테이블을 STACK 처리하기 SELECT * FROM TT5 UNPIVOT (구매건수 FOR 요일 IN(월,화,수,목,금,토,일)); // 구매건수는 VALUE인 데이터의 컬럼명 자리이고 요일은 STACK 만들 컬럼명 자리임 // DML, DDL, TDL, DCL // 서브쿼리를 사용해서 여러건 insert 하기 CREATE TABLE EMP3 ( EMPNO NUMBER(4) NOT NULL, ENAME VARCHAR2(10), DEPTNO NUMBER(2) ); Insert into EMP3 (EMPNO, ENAME, DEPTNO) SELECT EMPNO, ENAME, DEPTNO FROM EMP WHERE DEPTNO = 20; SELECT * FROM EMP3; // UPDATE UPDATE EMP3 SET DEPTNO = 10 WHERE ENAME = 'smith'; // DDL - CTAS (테이블 복제) CREATE TABLE EMP2 AS SELECT * FROM EMP; SELECT * FROM EMP2; DROP TABLE EMP2; // WHERE 조건 줘서 일부 데이터만 복제하기 CREATE TABLE EMP2 AS SELECT * FROM EMP WHERE SAL <= 3000; SELECT * FROM EMP2; // ALTER ALTER TABLE EMP2 ADD (BIRTHDAY DATE); ALTER TABLE EMP2 ADD (BIRTHDAY2 DATE, BIRTHDAY3 DATE); // 컬럼 생성 시 NOT NULL 속성 전달 불가 ALTER TABLE EMP2 ADD (BIRTHDAY4 DATE NOT NULL); // 데이터 없이 EMP2 테이블 구조만 복제 CREATE TABLE EMPEX AS SELECT * FROM EMP2 WHERE 1=2; SELECT * FROM EMPEX; ALTER TABLE EMPEX ADD (BIRTHDAY4 DATE NOT NULL); // 테이블에 데이터가 없을때는 컬럼 추가시 NOT NULL 설정 가능` // 컬럼 추가시 default를 추가하면 not null 속성을 갖는 컬럼 추가 가능 ALTER TABLE EMPEX ADD (FEELING VARCHAR2(30) DEFAULT 'GOOD' NOT NULL); INSERT INTO EMPEX VALUES (1, 'F', 'F', 1, TO_DATE('1981-05-01', 'yyyy-mm-dd'), 1234, 0, 1, TO_DATE('1981-05-01', 'yyyy-mm-dd'), TO_DATE('1981-05-01', 'yyyy-mm-dd'), TO_DATE('1981-05-01', 'yyyy-mm-dd'), TO_DATE('1981-05-01', 'yyyy-mm-dd'), DEFAULT); INSERT INTO EMPEX(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO, BIRTHDAY, BIRTHDAY2, BIRTHDAY3, BIRTHDAY4) VALUES (1, 'F', 'F', 1, TO_DATE('1981-05-01', 'yyyy-mm-dd'), 1234, 0, 1, TO_DATE('1981-05-01', 'yyyy-mm-dd'), TO_DATE('1981-05-01', 'yyyy-mm-dd'), TO_DATE('1981-05-01', 'yyyy-mm-dd'), TO_DATE('1981-05-01', 'yyyy-mm-dd')); // FEELING 컬럼을 NULLABLE로 바꾸기 ALTER TABLE EMPEX MODIFY (FEELING NULL); INSERT INTO EMPEX(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO, BIRTHDAY, BIRTHDAY2, BIRTHDAY3, BIRTHDAY4, FEELING) VALUES (1, 'F', 'F', 1, TO_DATE('1981-05-01', 'yyyy-mm-dd'), 1234, 0, 1, TO_DATE('1981-05-01', 'yyyy-mm-dd'), TO_DATE('1981-05-01', 'yyyy-mm-dd'), TO_DATE('1981-05-01', 'yyyy-mm-dd'), TO_DATE('1981-05-01', 'yyyy-mm-dd'), NULL); create table emploeyee ( id number(4), name varchar2(20), sal number(4), dname varchar2(100) ); insert into emploeyee values(0001, '홍길동', 1000, '아시아지부'); insert into emploeyee values(0002, '박길동', 2000, '아시아지부'); insert into emploeyee values(0003, '최길동', 3000, '아시아지부'); insert into emploeyee values(0004, '이길동', 4000, '남유럽지부'); insert into emploeyee values(0005, '김길동', 6000, '남유럽지부'); insert into emploeyee values(0006, '김길동', 8000, '남유럽지부'); select * from emploeyee; update emploeyee e1 set sal = (select max(sal) from emploeyee e2 where e1.dname = e2.dname) where sal <= (select avg(sal) from emploeyee);
 
2과목 13번 문제
2과목 13번 문제
 
2과목 64번 문제
2과목 64번 문제
시간 부족으로 몇 문제 밖에 못해봤지만 직접 데이터를 넣고
쿼리를 작은 단위로 쪼개서 실행시키면서 왜 이런 결과가 나오는지 이해하려고 노력했다.
 

 

공부 시간 & 공부량

 
일요일 시험이었는데 그 전주 수요일부터 시작해서 약 10일간 하루 3시간 정도 공부했고,
이동시간이나 잠자기전에 틈틈이 강의를 들었다.
노랭이는 백지상태로 1번(풀기), 강의 듣고 1번(정답 확인 및 오답),
시험전날 빠르게 훑으면서 1번(눈으로 복습) 이렇게 총 3번 봤다.
생각보다 생소한 개념이 많이 나온다. 이해하는데 시간이 필요하기 때문에 나처럼 비전공자이면
벼락치기를 하기 보다는 시간을 길게 잡아 조금씩 공부하는게 나은 거 같다.
 

 

시험 후기

 
1과목은 괜찮았고, 2과목은 생각보다 어렵게 느껴졌다.
노랭이 기출에서 본 문제 중에 3개?정도 그대로 나왔던거 같다.
 
  • 정규식 REGEXP_INSTR 함수 문제
    • SELECT REGEXP_INSTR('12345678','(123)(4(56)(78))', 1, 1, 0, 'i', 2) FROM DUAL;
  • UNION ALL 했을 때 첫번째 SELECT문의 컬럼 별칭이 컬럼명으로 출력되는지,
    • 두번째 SELECT문의 컬럼 별칭이 컬럼명으로 출력되는지 선택하는 문제
      notion image
  • 0 으로 나누는 연산에서 300/0 하면 0이 나오는지 error가 나오는지 하는 문제
    • (0/300, 300/0, 숫자/null > 0, error, null)
      정답
      정답
  • RollUp, GroupingSets 관련 문제
 
다 기억나지는 않지만 기억나는 것 중에 위 4개가 헷갈리고 어려웠던 거 같다.
총 50문제 중에 2과목에서 10문제 정도 생소하거나 좀 어렵게 느껴졌다.
 
notion image
 
6일에 사전점수가 나왔는데 합격이다~!
실무하다가 SQLP도 도전해보고 싶다.
 
SQLD는 기본 개념을 습득하는데 좋은 시험인 거 같다.
다만, 쿼리짜는 실력은 리트코드 같은데서 문제 풀면서 연습하거나
실무를 해야 늘 것 같다.
 
 
 
Share article

keepgoing