본문 바로가기
SK 행복성장캠퍼스/SQL

2020-09-14, SQL_5일차

by NickNuma 2020. 9. 16.

 

 

 

일단, 유저 추가하는 거부터
유저 추가는 관리자 계정에서 sql문으로 유저를 생성해주고 접속창에서 생성된 유저를 추가해줘야함.

create user scott identified by tiger;
grant resource, connect to scott;
-- db 자원 접근 권한 부여(생성 삭제 등), db 접속 권한 부여
show user;  
--현 접속 계정 확인

이렇게 유저 생성해준 이후에 접속창에서 유저 추가해주면 새로운 유저가 생성됨.


 


자... 5일차에는....
이게 총 3주차였는데.... 일단 select문 끝나고.. DML쪽 들어가니까 집중이 안 되서리... 그냥 진행은 했는데 뭘 했는지는 기억에 안 남았습니다.
그리고 근 4일을 복습 없이 쉬었는데... 다시 시작하려합니다.
항상 느끼는거지만.. 머리를 안 쓴다해도 손가락이라도 써서 진도는 밀리면 안된다...
(그러다가 미국 포스팅 꼴난다... 아.. 정말 미국 얘기는 못 할 듯. 서울가고 하면.. 진짜 시간 없음.)

쨌든, 5일차는

DML과 DDL에 대해서 배웠습니다. 그 중에서도 DDL에서의 제약조건이 가장 중요했습니다.

(실질적으로 1일을 더해서 5일, 6일차 강의입니다.)


 


DML  ( Data Manipulation Language :데이터 조작어 )
DB의 테이블에 새로운 데이터를 저장(INSERT)하거나 삭제(DELETE) 또는 수정 (UPDATAE) 및 병합(MERGE)할 때 사용하는 데이터 조작어

SQL 종류 명령문
Data Manipulation Language
(DML : 데이터 조작어)
INSERT  (데이터 입력)
UPDATE (데이터 수정)
DELETE  (데이터 삭제)
MERGE  (데이터 병합)

 


insert : 테이블에 데이터를 저장하기 위한 데이터 조작어 

단일 insert문     :      단일 테이블에 하나의 행을 저장하는 insert문

< 문법 >

INSERT INTO 테이블명 [(컬럼명,컬럼명2,...)]
VALUES ( 값, 값2, ... )

< 예제 >

--column 생성
INSERT INTO dept( deptno, dname, loc )
VALUES ( 50 ,'개발','서울');

---column 생략 가능 (Primary key, not null => 생략 불가)
INSERT INTO dept(deptno, dname )
VALUES ( 70 ,'인사');

--해당 테이블에 순서대로 값 자동 대입
INSERT INTO dept
VALUES ( 60 ,'인사','경기');
-- insert into 컬럼 생략 => values 테이블의 컬럼과 순서 일치

--**Error 상황**
--insert into 테이블의 컬럼을 생략했을 때는, values에 모든 값을 지정해줘야한다.
INSERT INTO dept
VALUES ( 60 ,'인사');  --이때에는 values의 컬럼의 값을을 모두 지정해줘야한다.         

 


복수행 insert문     :    단일 테이블에 여러 행을 저장하는 복수행 INSERT 문

< 문법 >

INSERT INTO 테이블명 [(컬럼명,컬럼명2,...)]
Subquery;

< 예제 >

--다중 insert문,   한 번에 값 삽입.
INSERT INTO mydept
SELECT deptno,dname,loc
FROM dept;


 


다중 테이블 다중행 INSERT 문     :    여러 테이블에 복수 데이터를 저장하는 다중행 INSERT문

< 문법 >

INSERT ALL
[WHEN 조건식 THEN]
INTO 테이블1 VALUES ( 컬럼명,컬럼명2,...,컬럼명n)
[WHEN 조건식2 THEN]
INTO 테이블2 VALUES ( 컬럼명,컬럼명2,...,컬럼명n)
Subquery;

< 예제 >

INSERT ALL
INTO myemp_hire VALUES ( empno,ename,hiredate,sal )
INTO myemp_mgr VALUES ( empno,ename,mgr )
SELECT empno,ename,hiredate,sal,mgr
FROM emp;
INSERT ALL
WHEN sal = 800 THEN
	INTO table1 VALUES ( empno,ename,hiredate,sal )
WHEN sal < 2500 THEN
	INTO table2 VALUES ( empno,ename,mgr )
SELECT empno,ename,hiredate,sal,mgr
FROM emp;

 


UPDATE 문     :    테이블에 저장된 데이터를 수정하기 위해서 사용되며 한 번에 여러 개의 행들을 변경 가능

< 문법 >

UPDATE 테이블명
SET 컬럼명=변경할값[, 컬럼명1=변경할값]
[WHERE 조건식];

< 예제 >

update mydept
set dname='영업', loc='경기'    --개발, 서울을 변경
where deptno = 50;

UPDATE mydept
SET dname = (  SELECT dname
                 FROM dept
                WHERE deptno = 10)
    ,loc= ( SELECT loc
              FROM dept
             WHERE deptno=20)
WHERE deptno = 60;


 


DELETE 문     :     테이블에 저장된 데이터를 삭제하기 위해서 사용되며 한 번에 여러 개의 행들을 삭제 가능

< 문법 >

DELETE FROM 테이블명
[WHERE 조건식];

< 예제 >

DELETE FROM mydept
WHERE deptno = 50;


 


서브쿼리를 이용한 delete 문     :    서브쿼리가 실행된 결과값으로 테이블의 데이터를 삭제
이 방법을 사용하면 다른 테이블에 저장된 데이터를 사용하여 특정 데이터를 삭제할 수 있다.

< 문법 >

DELETE
FROM 테이블명
WHERE 컬럼명 = ( SubQuery );

<예제 >

--DEPT테이블에서 부서번호가 20인 부서위치와 동일한 위치에 해당하는 행을 mydept테이블에서 삭제하는 SQL문

DELETE
FROM mydept
WHERE loc =   (SELECT loc
                 FROM dept
                WHERE deptno = 20);


 


MERGE 문 : 구조가 같은 2개의 테이블을 비교하여 하나의 테이블로 합치기 위한 데이터 조작어

< 문법 >

MERGE INTO 테이블1 별칭
USING (테이블명2|뷰|서브쿼리) 별칭
ON (조인조건)
WHEN MATCHED THEN
	UPDATE SET
		컬럼명=값,
		컬럼명1=값1
	[WHERE 조건식]
	[DELETE WHERE 조건식]
WHEN NOT MATCHED THEN
	INSERT ( 컬럼 목록)
	VALUES ( 값 목록 )
	[WHERE 조건식];

< 예제 >

--1월 판매정보를 가진 pt_01 테이블과 통합 테이블인 pt_total을 병합하여 1월 판매현황을 관리

MERGE INTO p_total total
USING pt_01 p01
ON ( total.판매번호 = p01.판매번호)
WHEN MATCHED THEN
    UPDATE SET total.제품번호 = p01.제품번호
WHEN NOT MATCHED THEN
    INSERT VALUES ( p01.판매번호, p01.제품번호, p01.수량, p01.금액);

MERGE INTO p_total total
USING pt_02 p02
ON ( total.판매번호 = p02.판매번호)
WHEN MATCHED THEN
    UPDATE SET total.제품번호 = p02.제품번호
WHEN NOT MATCHED THEN
    INSERT VALUES ( p02.판매번호, p02.제품번호, p02.수량, p02.금액);

---pt_01 값 변경
update pt_01
set 수량 = 13
where 판매번호 = '20170101';

update pt_01
set 수량 = 9
where 판매번호 = '20170103';
--변경된 pt_01의 정보를 p_total에 수정/변경/병합

MERGE INTO p_total total
USING pt_01 p01
ON ( total.판매번호 = p01.판매번호)
WHEN MATCHED THEN
    UPDATE SET total.제품번호 = p01.제품번호, total.수량 = p01.수량    
WHEN NOT MATCHED THEN
    INSERT VALUES ( p01.판매번호, p01.제품번호, p01.수량, p01.금액);

 


트랜잭션  : 데이터베이스의 논리적인 작업 단위로서 분리될 수 없는 한 개 이상의 데이터베이스 조작
하나의 트랜잭션 = 하나 이상의 SQL문장  /  트랜잭션의 대상이 되는 SQL문 = DML 문

예)) 계좌 이체 작업
계좌 이체시에 UPDATE문과 INSERT문을 연달아 두 계좌에서 작업함. (논리적으로 1개의 작업)
A계좌에 잔액 감소 UPDATE문은 성공했으나 B계좌에 A계좌에서 들어온 돈의 INSERT문이 실패할 경우 매우 심각한 오류 발생.  ==> 논리적으로 1개의 작업으로 처리되야만 함. <<<- Transaction (트랜잭션)


TCL (Transaction Control Language) : 트랜젝션 제어를 위한 명령어
여러 DML 작업을 논리적으로 1개의 작업처럼 처리하도록 도와주는 명령어

  • COMMIT : DML문에 의해 실행된 작업으로 인해 변경된 데이터를 메모리에서부터 데이터베이스에 물리적 파일로 저장하고 현재의 트랜잭션을 종료하는 명령어
  • ROLLBACK [TO SAVEPOINT 이름] : COMMIT을 하지 않은, 작업이 종료 후 저장되지 않고 아직 메모리에 머물러있는 모든 데이터의 변경 사항을 취소하고 현재의 트랜잭션을 종료하는 명령어
  • SAVEPOINT 이름 : 진행중인 트랜잭션을 특정 이름으로 지정하는 명령어.
SAVEPOINT A01;
COMMIT;
ROLLBACK;

Lock 경합

--DB에서 작업이 있으면 그 작업자의 작업이 정상적으로 끝나기 전까지 DB 데이터 접속, 변경에 접근할 수 없다. => Lock 상황

--commit, rollback 과 같은 명령으로 정상 종료 해줘야 Lock이 풀리고 타인이 DB에 접속 가능함.

--DB에 접속한 사용자(관리자) A와 B가 존재할 때, A가 하나의 트랜잭션을 시행 중이라고 한다면 A가 commit이나 rollback 등의 TCL을 사용하여 트랜잭션을 종료하기 전까지는 사용자(관리자) A 이외의 다른 사용자(관리자)는 해당 DB에 접속할 순 있어도 DB에 명령을 내릴 순 없다.


 


DDL(Data Definition Language)  :  데이터베이스의 구조를 생성하거나 수정 및 삭제하는데 사용되는 SQL문
자동으로 COMMIT 된다.

SQL 종류 명령문
Data Definition Language
(DDL : 데이터 정의어)
CREATE(데이터베이스 객체 생성)
ALTER(데이터베이스 객체 변경)
DROP(데이터베이스 객체 삭제)
RENAME(데이터베이스 객체이름 변경)
TRUNCATE(객체 정보 절삭)

테이블 생성
< 문법 >

CREATE TABLE [스키마].테이블명
( 컬럼명 데이터타입 [DEFAULT 값 | 제약조건][,...] );

< 예제 >

CREATE TABLE scott.employee
( empno NUMBER(4),
    ename VARCHAR2(20),
    hiredate DATE,
    sal NUMBER(7,2));

CTAS(씨탁스) : 서브쿼리를 이용하여 존재하는 테이블을 사용하여 새로운 테이블을 생성하는 방법

< 문법 >

CREATE TABLE 테이블명 [(컬럼명,컬럼명2)]
AS
Subquery;

< 예제 >

-- where 1 = 2 절로 value를 다 없애고 그냥 테이블 구조만 복사해서 생성.

CREATE TABLE mydept	--create => DDL ===> 자동 commit
AS
SELECT * FROM dept
WHERE 1=2;

Default 옵션 : DEFAULT 옵션을 사용하여 값을 지정하지 않은 컬럼에 자동으로 널(null)값이 저장되는 것을 방지

CREATE TABLE employee2
( empno NUMBER(4),
    ename VARCHAR2(20),
    hiredate DATE DEFAULT SYSDATE,
    sal NUMBER(7,2));

 


제약 조건 ( Constraints Rule )

--1) 제약 조건 종류
--primary key 
--==> 테이블당 1번만 설정 가능  
--==> 지정된 컬럼은 반드시 null이 아닌 유일한 값 저장 ( not null + unique )
--==> 지정된 컬럼은 복수컬럼이 가능 (복합컬럼 가능)
--==> 지정하면 자동 인덱스 생성
--    인덱스는 검색 속동 향상 목적으로 만든 객체
--==> 테이블에 PK적용하는 방법 2가지 제공
--    가. 테이블 레발
--    나. 컬럼 레벨
--==> 목적 : 레코드 식별
--
--unique ( uk )
--==> 테이블당, 여러번 설정 가능
--==> 지정된 컬럼은 반드시 유일한 값을 저장해야. Null가능 ( null + unique )
--==> 지정된 컬럼은 복수컬럼 가능 (복합컬럼이 가능)
--==> 지정하면 자동으로 index 생성
--    인덱스는 검색 속동 향상 목적으로 만든 객체
--==> 테이블에 uk 적용하는 방법 2가지 제공
--    가. 테이블 레벨
--    나. 컬럼 레벨
--==> 목적: 유일한 값 저장 
--
--not null    ( nn )
--==> 테이블 당 여러번 설정 가능
--==> 지정된 컬럼은 반드시 값을 가져야한다.
--==> 테이블에 nn 적용하는 방법 1가지 제공 ==> 컬럼 레벨
--==> 목적 : 반드시 값 저장
--#######################################################
--*기본적으로 모든 컬럼 = null 허용 --> not null로 제약으로 수정됨.
--  not null 제외, 4가지 제약조건은 추가되는 (제약)조건이다.
--  
--  테이블 레벨 = 제약조건을 추가하는 문법과 동일
--  따라서, 제약조건을 수정하는 형태의 not null ==> 테이블 레벨 사용 불가
--
--  테이블을 먼저 생성하고 나중에 제약조건 설정 가능 == 제약조건 추가하는 테이블 문법
--  not null ==> modify키워드로 제약조건 설정
--  나머지 4개의 제약조건은 add키워드로 제약조건 설정
--######################################################
--
--check ( ck )
--==> 테이블 당 여러번 설정 가능
--==> 테이블에 ck 적용하는 방법 2가지 제공
--    가. 테이블 레벨
--    나. 컬럼 레벨
--==> 목적 : 임의의 값이 아닌 사용자가 지정된 값 저장 및 검사
--    예> age 컬럼 : 1000
--        gender : '남자' 또는 '여자, '남'/'녀', 'f'/'m'에서 '남'/'녀' 형식만 사용 강제.
--        중학교: 1학년, 2학년, 3학년
--    
--foreign key
--==> 테이블 당 여러번 설정 가능
--==> 지정하면 fk가 참조하는 master 테이블의 컬럼 중 반드시 pk또는 uk컬럼만 참조 가능
--==> 따라서, fk가 갖을 수 있는 값은 master의 pk, uk, null 값
--==> 테이블에 fk 적용하는 방법 2가지 제공
--    가. 테이블 레벨
--    나. 컬럼 레벨

제약 조건 타입 설명
PRIMARY KEY 해당 컬럼 값은 반드시 존재해야 하고 유일해야 한다.
즉, NOT NULL 과 UNIQUE 조건을 결합한 형태이다.
컬럼 레벨/테이블 레벨 방식 모두 지원한다.
UNIQUE 테이블 내에서 해당 컬럼 값은 항상 유일한 값을 갖는다.
컬럼 레벨/테이블 레벨 방식 모두 지원한다.
NOT NULL 해당 컬럼 값으로 NULL을 허용하지 않는다.
컬럼 레벨 방식만 지원한다.
CHECK 해당 컬럼에 가능한 데이터 값의 범위나 사용자 조건을 지정한다.
컬럼 레벨/테이블 레벨 방식 모두 지원한다.
FOREIGN KEY 해당 컬럼의 값이 다른 테이블의 컬럼의 값을 참조해야한다.
즉, 참조되는 컬럼에 없는 값은 저장이 불가능하다.
컬럼 레벨/테이블 레벨 방식 모두 지원한다.

 


primary key : 식별 기능을 가진 컬럼
유일해야 되고 널(null)값은 포함할 수 없음을 보증하며 자동으로 UNIQUE INDEX 객체가 생성된다

1)컬럼 레벨 방식 (수정하는 방식)

< 문법 >

CREATE TABLE [스키마].테이블명
( 	컬럼명 데이터타입 [CONSTRAINT 제약조건명] PRIMARY KEY,
	컬럼명 데이터타입,
	...
);

< 예제 >

CREATE TABLE department
(   deptno NUMBER(2) CONSTRAINT department_deptno_pk PRIMARY KEY,
    dname VARCHAR2(15),
    loc VARCHAR2(15)    );


테이블의 제약조건 정보 얻기

select * 
from user_constraints
where table_name = 'DEPARTMENT';

select * 
from user_tables
where table_name = 'DEPARTMENT';

테이블의 인덱스 정보 얻기

select * 
from user_indexes
where table_name = 'DEPARTMENT';


2)테이블 레벨 방식 (기본 키 제약조건을 추가하는 문법)

< 문법 >

CREATE TABLE [스키마].테이블명
( 	컬럼명 데이터타입,
	컬럼명 데이터타입,
	[CONSTRAINT 제약조건명] PRIMARY KEY(컬럼명[,컬럼명2)
);

< 예제 >

CREATE TABLE department2
(   deptno NUMBER(2),
    dname VARCHAR2(15),
    loc VARCHAR2(15) ,
    CONSTRAINT department2_deptno_pk PRIMARY KEY(deptno)
);

 


UNIQUE 제약 조건  : 기본 키가 아닌 경우에도 컬럼의 모든 데이터가 유일해야 되는 경우
UNIQUE INDEX가 생성되어 빠른 검색 효과 
Primary Key와 차이점 : 하나의 테이블에 UNIQUE 제약조건은 여러 개 지정할 수 있고 널(null)값도 저장할 수 있다.

1)컬럼 레벨 방식 (수정하는 방식)

< 문법 >

CREATE TABLE [스키마].테이블명
(   컬럼명 데이터타입 [CONSTRAINT 제약조건명] UNIQUE,
    컬럼명 데이터타입,
    ...
);

< 예제 >

CREATE TABLE department4
(   deptno NUMBER(2) CONSTRAINT department4_deptno_pk PRIMARY KEY,
    dname VARCHAR2(15) CONSTRAINT department4_dname_uk UNIQUE,
    loc VARCHAR2(15) );

 

2)테이블 레벨 방식 (추가하는 방식)

< 문법 >

CREATE TABLE [스키마].테이블명
(	컬럼명 데이터타입,
	컬럼명 데이터타입,
	...
	[CONSTRAINT 제약조건명] UNIQUE(컬럼명[,컬럼명2])
);

< 예약 >

CREATE TABLE department5
( deptno NUMBER(2) CONSTRAINT department5_deptno_pk PRIMARY KEY,
    dname VARCHAR2(15),
    loc VARCHAR2(15),
    CONSTRAINT department5_dname_uk UNIQUE(dname)
);

 


NOT NULL 제약 조건  :  해당 컬럼에 널(null)값이 저장되는 것을 방지하는 제약조건
반드시 컬럼 레벨 방식으로만 사용, 테이블 레벨 방식 사용 불가

컬럼 레벨 방식 (수정하는 방법)

< 문법 >

CREATE TABLE [스키마].테이블명
( 컬럼명 데이터타입 [CONSTRAINT 제약조건명] NOT NULL,
	컬럼명 데이터타입,
	...
);

< 예제 >

CREATE TABLE department6
( deptno NUMBER(2) CONSTRAINT department6_deptno_pk PRIMARY KEY,
    dname VARCHAR2(15) CONSTRAINT department6_dname_uk UNIQUE,
    loc VARCHAR2(15) CONSTRAINT department6_loc_nn NOT NULL);

 


CHECK  : 해당 컬럼에 저장되는 데이터를 검사하여 조건과 일치하는 데이터만 저장이 가능하도록 처리하는 제약조건

1)컬럼 레벨 방식 (수정하는 방법)

< 문법 >

CREATE TABLE [스키마].테이블명
( 컬럼명 데이터타입 [CONSTRAINT 제약조건명] CHECK(조건식) ,
	컬럼명 데이터타입,
	...
);

< 예제 >

CREATE TABLE department7
( deptno NUMBER(2) ,
    dname VARCHAR2(15)
    CONSTRAINT department7_dname_ck CHECK( dname IN('개발','인사')) ,   --check (age < 100 )
    loc VARCHAR2(15)
);

 

2) 테이블 레벨 방식 (추가하는 방법)
< 문법 >

CREATE TABLE [스키마].테이블명
( 컬럼명 데이터타입 ,
	컬럼명 데이터타입,
	...,
	[CONSTRAINT 제약조건명] CHECK(조건식)
);

< 예제 >

CREATE TABLE department8
( deptno NUMBER(2) ,
    dname VARCHAR2(15),
    loc VARCHAR2(15),
    CONSTRAINT department8_dname_ck CHECK( dname IN('개발','인사'))
);

 


FOREIGN KEY (외래키, 참조키) : 다른 테이블을 참조할 때 올바른 데이터값만 참조 가능하도록 제약하는 방법

1)컬럼 레벨 방식 (수정하는 방법)

< 문법 >

CREATE TABLE [스키마].테이블명
( 	컬럼명 데이터타입 [CONSTRAINT 제약조건명] REFERENCES 부모테이블명(컬럼명), 
	컬럼명 데이터타입,
	...
);

< 예제 >

Master Table

CREATE TABLE dept02
( deptno NUMBER(2) CONSTRAINT dept02_deptno_pk PRIMARY KEY,
    dname VARCHAR2(15),
    loc VARCHAR2(15)
);

Child / Slave Table (컬럼 레벨 방식)

CREATE TABLE emp02
( empno NUMBER(4) CONSTRAINT emp02_empno_pk PRIMARY KEY,
    ename VARCHAR2(15),
    deptno NUMBER(2) CONSTRAINT emp02_deptno_fk REFERENCES dept02(deptno) --foriegn key
);

 

2)테이블 레벨 방식 (추가하는 방법)

< 문법 >

CREATE TABLE [스키마].테이블명
( 	컬럼명 데이터타입,
	컬럼명 데이터타입,
	...,
	[CONSTRAINT 제약조건명] FOREIGN KEY(컬럼명) REFERENCES 부모테이블명(컬럼명)
);

< 예제 >

Child / Slave Table

CREATE TABLE emp03
( empno NUMBER(4) CONSTRAINT emp03_empno_pk PRIMARY KEY,
    ename VARCHAR2(15),
    deptno NUMBER(2),
    CONSTRAINT emp03_deptno_fk FOREIGN KEY(deptno) REFERENCES dept02(deptno)       --foriegn key
);

FOREIGN KEY 제약조건의 추가 옵션
부모와 자식 테이블의 연결로 인해 컬럼 삭제 불가 ==> on delete cascade, on delete set null로 child table 생성하면 삭제 가능

1) ON DELETE SET NULL 방법 ( 예시>컬럼 레벨 방식에서 )
부모 테이블에서 해당 컬럼을 삭제하면 자식 테이블에서 해당 컬럼을 참조하던 컬럼의 값은 NULL이 된다.

CREATE TABLE emp02
( empno NUMBER(4) CONSTRAINT emp02_empno_pk PRIMARY KEY,
	ename VARCHAR2(15),
	deptno NUMBER(2)
	CONSTRAINT emp02_deptno_fk REFERENCES dept02(deptno) ON DELETE SET NULL
);

 

2) ON DELETE CASCADE 방법 ( 예시 > 테이블 레벨 방식에서 )
부모 테이블에서 해당 컬럼을 삭제하면 자식 테이블에서 해당 컬럼을 참조하던 컬럼도 자동 삭제된다.

CREATE TABLE emp03
( empno NUMBER(4) CONSTRAINT emp03_empno_pk PRIMARY KEY,
    ename VARCHAR2(15),
    deptno NUMBER(2),
    CONSTRAINT emp03_deptno_fk FOREIGN KEY(deptno)
    REFERENCES dept02(deptno) on DELETE CASCADE
);

 


테이블 삭제

< 문법 >

--복구 가능
DROP TABLE 테이블명 [CASCADE CONSTRAINTS];

-- 완전 삭제
drop table 테이블명 purge;

< 예시 >

--일반 삭제
drop table dept02;

--자식 테이블의 Foreign key를 제거하여 부모 테이블인 dept02를 제거할 수 있게함.
--제약조건 제거하고 삭제
drop table dept02 cascade constrints;
명령어 설명
FLASHBACK TABLE 테이블명 TO BEFORE DROP; 삭제된 테이블을 복구.
SHOW RECYCLEBIN RECYCLEBIN 객체 정보 조회
PURGE RECYCLEBIN RECYCLEBIN 객체 정보 삭제
DROP TABLE 테이블명 PURGE 테이블 완전 삭제( 복구 불가 )

 

교훈:
기분이 좋던 싫던.
어렵던 쉽던.
진도 밀리지 말고 그날 그날 하자.

반응형

'SK 행복성장캠퍼스 > SQL' 카테고리의 다른 글

2020-09-14, SQL_5일차_연습문제  (0) 2020.09.18
2020-09-11, SQL_4일차_연습문제  (0) 2020.09.12
2020-09-11, SQL_4일차  (0) 2020.09.12
2020-09-10, SQL_3일차_연습문제  (0) 2020.09.11
2020-09-10, SQL_3일차  (0) 2020.09.11

댓글