<7월 7일 점심시간 문제>


hr 계정의 employees 테이블을 다음과 같이 백업합니다.

create  table  employees_backup 
  as
  select * from employees;

그리고 update 문을 이용해서 employees_backup 테이블의 데이터 일부를 수정합니다.
수정은 여러분들이 마음껏 수정하시면 됩니다.


수정할때 not null 걸려있는 애들은 null 로 못바꿈

그리고 짝꿍의 employees_backup 테이블과 나의 employees_backup 테이블의 데이터의 차이를 확인합니다.
차이가 나는 데이터가 무엇인지 확인하세요. 양쪽으로 다 확인하세요 !
(minus 두가지 경우로 다 써서 확인해보기)

복습 (delete, merge)

  • merge 문은 특정 테이블에 insert, update, delete를 한번에 수행하는 명령어입니다.

문제 466.
운영 db와 테스트db가 여러분들 컴퓨터에 하나의 db에 있다고 가정하고 하기 위해서
두개의 테이블을 아래와 같이 생성하세요

  • 운영 db 테이블
create table operate_emp
 as
  select * from emp;
  • 테스트 db 테이블
    create table test_emp
    as
     select * from emp;

문제 467. test_emp테이블에서 직업이 SALESMAN 과 MANAGER 인 사원들의 데이터를 지우시오

delete from test_emp
 where job in ('SALESMAN','MANEGER') ;

문제 468. test_emp 테이블에서 직업이 ANALYST 와 CLERK 인 사원들의 월급을 0 으로 변경하시오

update test_emp
set sal = 0
where job in ('ANALYST','CLERK');

commit;

merge 참고하기

문제 469. (성해보여주기)
operate_emp 테이블로 test_emp 테이블을 merge 하는데,
operate_emp 테이블에는 존재하는 데이터인데 test_emp 테이블에는 존재하지 않는 데이터는 test_emp 테이블에 입력하고,
양쪽 다 존재하는데 데이터가 틀리면 operate_emp 의 데이터로 test_emp 에 업데이트하시오 (?)

merge into test_emp t 
using operate_emp o
on ( t.empno = o.empno )      -> 연결고리 (join 조건)
when matched then             -> 연결고리에 의해서 매치된다면
 update set t.sal = o.sal     -> 월급을 업데이트해라
            t.comm = o.comm      (이런식으로 여러개도 쓸 수 있음!)
when not matched then         -> empno가 매치되지 않는건,
 insert (t.empno, t.ename, t.job, t.sal, t.comm, t.hiredate, t.mgr, t.deptno )
  values (o.empno, o.ename, o.job, o.sal, o.comm, o.hiredate, o.mgr, o.deptno );                
   -> test 데이터에 operate 데이터를 입력해라
  • 다소 문법이 복잡해보이지만 성능이 좋아서 merge 문을 많이 사용한다.
  • truncate 시키고 다시 가져오는 것보다는 merge로 몇개씩 바꾸는게 더 낫다.
  • 지금은 sal 이 다르다는걸 알아서 t.sal=o.sal 이렇게 쓰는데 만약 어떤 데이터가 다른지 모른다면, 아예 모든 데이터를 다 써줘도 된다. 그러면 자기가 알아서 검색 해본다음에 업데이트 시킨다.
    t.sal=o.sal t.comm=o.comm...

    문제 470.
    우리반 테이블을 emp17_backup 으로 백업하세요.

    create table emp17_backup
     as
     select * from emp17;

    rownum 활용해서 데이터 정리

    문제 471.
    emp17 테이블의 데이터를 아래와 같이 지우시오

    delete from emp17
     where rownum < 10;
    
     commit;
  • 백업과 본 테이블을 맞춰주려면, 가장 간단한 방법은 truncate 하고 불러오는게 간단하긴 하지만, 데이터가 많다면 너무 오래걸리기 때문에 merge 하는게 좋다.

문제 472. (요거 꼭 확인해보삼삼)
emp17_backup 의 내용으로 emp17의 데이터를 merge 하시오
(같은 데이터라면 update 하고, 없으면 insert 하시오)

merge into emp17_ e
using emp17_backup s
on ( e.empno = s.empno )
when matched then
update set  e.ename = s.ename,
            e.gender = s.gender,
            e.birth = s.birth,
            e.age = s.age,
            e.telecom = s.telecom,
            e.email = s.email,
            e.major = s.major,
            e.address = s.address
when not matched then
  insert (e.empno, e.ename, e.gender, e.birth, e.age, e.telecom, e.email, e.major, e.address )
   values (s.empno, s.ename, s.gender, s.birth, s.age, s.telecom, s.email, s.major, s.address );  
  • empno 는 위에 매치조건이기때문에 update 에 안써줌 (이미 매치가 되어야 이게 작동한다는 조건이기 때문에, 매치가 된다는 가정하임!!)
    -> on 절에 쓴거는 update 에 쓰면 오류남!

문제 473.
이번에는 emp17 테이블을 truncate 시키고 emp17backup 으로 데이터를 입력하시오
(truncate 는 조심해서 써야함,,,ㅠ
ㅠ)

truncate table emp17;

insert into emp17
 select *
  from emp17_backup;
  • merge 하려는 2개의 테이블 사이의 데이터의 변경의 차이가 심하고
    둘다 대용량 테이블이 아니면 위의 방법truncate 이 더 간단하긴함!
    하지만 truncate 의 부담감이 있음
    -> 일반 개발자들은 DBA 한테 truncate 의 권한을 안주는 경우가 많음

문제 474. market_2022 테이블을 백업하세요

create table market_2022_backup
as
 select *
  from market_2022;

문제 475. market_2022 테이블의 데이터를 일부 지우시오
(대용량 테이블이라 시간 좀 걸릴것)

delete from market_2022
 where rownum < 156405;

 commit;

문제 476. market_2022 테이블의 상호명을 전부 null 로 변경하시오

update  market_2022
 set 상호명 = null ; 

 commit;

문제 477. market_2022 테이블의 데이터를 market_2022_backup 테이블의 데이터로 merge 하시오 (밑에 하는 방법 적어놓음)

merge into market_2022 a
using market_2022_backup b
on ( a.상가업소번호 = b.상가업소번호 )
when matched then
update set  a.상호명=b.상호명,
            a.지점명=b.지점명,
            a.상권업종대분류코드=b.상권업종대분류코드,
            a.상권업종대분류명=b.상권업종대분류명,
            a.상권업종중분류코드=b.상권업종중분류코드,
            a.상권업종중분류명=b.상권업종중분류명,
            a.상권업종소분류코드=b.상권업종소분류코드,
            a.상권업종소분류명=b.상권업종소분류명,
            a.표준산업분류코드=b.표준산업분류코드,
            a.표준산업분류명=b.표준산업분류명,
            a.시도코드=b.시도코드,
            a.시도명=b.시도명,
            a.시군구코드=b.시군구코드,
            a.시군구명=b.시군구명,
            a.행정동코드=b.행정동코드,
            a.행정동명=b.행정동명,
            a.법정동코드=b.법정동코드,
            a.법정동명=b.법정동명,
            a.지번코드=b.지번코드,
            a.대지구분코드=b.대지구분코드,
            a.대지구분명=b.대지구분명,
            a.지번본번지=b.지번본번지,
            a.지번부번지=b.지번부번지,
            a.지번주소=b.지번주소,
            a.도로명코드=b.도로명코드,
            a.도로명=b.도로명,
            a.건물본번지=b.건물본번지,
            a.건물부번지=b.건물부번지,
            a.건물관리번호=b.건물관리번호,
            a.건물명=b.건물명,
            a.도로명주소=b.도로명주소,
            a.구우편번호=b.구우편번호,
            a.신우편번호=b.신우편번호,
            a.동정보=b.동정보,
            a.층정보=b.층정보,
            a.호정보=b.호정보,
            a.경도=b.경도,
            a.위도=b.위도
when not matched then
  insert (a.상가업소번호,a.상호명,a.지점명,a.상권업종대분류코드,a.상권업종대분류명,a.상권업종중분류코드,a.상권업종중분류명,a.상권업종소분류코드,a.상권업종소분류명,a.표준산업분류코드,a.표준산업분류명,a.시도코드,a.시도명,a.시군구코드,a.시군구명,a.행정동코드,a.행정동명,a.법정동코드,a.법정동명,a.지번코드,a.대지구분코드,a.대지구분명,a.지번본번지,a.지번부번지,a.지번주소,a.도로명코드,a.도로명,a.건물본번지,a.건물부번지,a.건물관리번호,a.건물명,a.도로명주소,a.구우편번호,a.신우편번호,a.동정보,a.층정보,a.호정보,a.경도,a.위도 )
   values (b.상가업소번호,b.상호명,b.지점명,b.상권업종대분류코드,b.상권업종대분류명,b.상권업종중분류코드,b.상권업종중분류명,b.상권업종소분류코드,b.상권업종소분류명,b.표준산업분류코드,b.표준산업분류명,b.시도코드,b.시도명,b.시군구코드,b.시군구명,b.행정동코드,b.행정동명,b.법정동코드,b.법정동명,b.지번코드,b.대지구분코드,b.대지구분명,b.지번본번지,b.지번부번지,b.지번주소,b.도로명코드,b.도로명,b.건물본번지,b.건물부번지,b.건물관리번호,b.건물명,b.도로명주소,b.구우편번호,b.신우편번호,b.동정보,b.층정보,b.호정보,b.경도,b.위도 );

많은 merge 문 만드는 방법 (dictionary 사전 활용)☆☆☆

(문제 477 해설)

  • 컬럼이름들 보는 다른 방법

1. 먼저 column 리스트를 알아야한다. (다 써야하는데 일일히 하나하나 쓰긴 복잡하니까)

select *
 from dictionary
  where table_name like '%DBA%TAB%COLUMN%'; (대문자로!!)

-> 사전 리스트 중에 column 을 포함하고 있는 사전들을 보여달라는 문법


-> 유저 테이블의 컬럼들을 보여준다는 사전
그 다음,

select column_name
 from dba_tab_columns
 where table_name='MARKET_2022';

위의 사전이름을 from 에 쓰면

라고 컬럼 이름이 쭉 뜬다.

2. 연결연산자로 update 문법 만들어주기

select 'a.' || column_name || '=' || 'b.' || column_name || ','
 from dba_tab_columns
 where table_name='MARKET_2022';


연결연산자 사용해서, 'update set' 에 들어갈 업데이트 될 컬럼문을 만들어준다.
이중에서 상가업소번호는 빼기~! 맨 마지막 ',' 도 빼기!

3. 연결연산자 + listagg 사용해서 insert 문법 만들어주기

그다음 insert 문 ( , , , ) 만들기

select 'a.' || column_name || ','

이렇게 해도 되지만 보기 안좋아서, listagg 사용하기

select listagg ('a.' || column_name ,',')
 from dba_tab_columns
 where table_name='MARKET_2022';


그다음 b 도 똑같이 만들어줘야함

select listagg ('b.' || column_name ,',')
 from dba_tab_columns
 where table_name='MARKET_2022';

4. 구한 정보들 입력하기

그리고 merge 문에 하나씩 입력하면 됨!

merge into test_emp t 
using operate_emp o
on ( t.empno = o.empno )      -> 연결고리 (join 조건)
when matched then             -> 연결고리에 의해서 매치된다면
 update set t.sal = o.sal     -> 월급을 업데이트해라
            t.comm = o.comm      (이런식으로 여러개도 쓸 수 있음!)
when not matched then         -> empno가 매치되지 않는건,
 insert (t.empno, t.ename, t.job, t.sal, t.comm, t.hiredate, t.mgr, t.deptno )
  values (o.empno, o.ename, o.job, o.sal, o.comm, o.hiredate, o.mgr, o.deptno );                
   -> test 데이터에 operate 데이터를 입력해라

※ 위와 같이 dba_ 로 시작하는 테이블들이 바로 데이터 사전 관련한 테이블들 입니다.

문제 478. c##scott 유저가 소유하고 있는 테이블 리스트를 확인하시오

select *
 from user_tables;

3가지 사전 활용법

  1. user_tables : c##scott 유저가 소유하고 있는 테이블 리스트를 확인
  2. all_tables : c##scott 유저가 소유하고 있는 테이블 + 엑세스 권한 받은 테이블들 확인
  3. dba_tables : db에 있는 모든 테이블 리스트를 다 확인 (only dba 의 사전)
  • 뒤에 tables 를 붙인곳에 다른거 넣어서 다르게 활용할 수 있음!!
    ex) dbatab_columns, user어쩌구


    1) user_tab_columns : c##scott 유저가 소유하고 있는 테이블들의 컬럼정보를 확인하는 사전
    2) all_tab_columns : c##scott 유저가 소유하고 있는 테이블 + 엑세스 권한 받은 테이블들의 컬럼정보를 확인하는 사전
    3) dba_tab_columns : db에 있는 모든 테이블들의 컬럼정보 확인하는 사전


  • 위의 데이터 사전들이 뭐가 있는지 외울 필요는 없고!!
    아래의 쿼리를 조회해서 필요한 사전들을 찾아냅니다.

    select *
     from dictionary
     where  table_name like '%보고싶은키워드를 대문자로%'

    ex. 컬럼정보가 보고싶다면,

     select *
     from dictionary
     where  table_name like '%COLUMN%'

    ex2. db를 포함하고, tab을 포함하고, column 을 포함하는 데이터 사전을 보여줘!
    ->

    select *
    from dictionary
    where  table_name like '%DB%TAB%COLUMN%'
  • % 로 연결해서 쭉쭉 써주면 됨


※ 위와 같이 merge 문을 이용하지 않는다면,
다른 방법으로 두 테이블 사이에 데이터의 일치를 맞춰주는 SQL이 뭐가 있는가?

-> 상호관련 서브쿼리를 사용한 update 문 (악성 sql임, 성능 bad 인데 개발자들이 많이씀)
(오후에 설명해주시기로)

083. 락(LOCK) 이해하기

lock : 세션(유저)이 특정 데이터를 수정하게 되면 commit 하기 전까지 수정한 행(row) 에 lock을 겁니다.

특정 세션이 변경한 데이터를 다른 세션이 변경하지 못하도록 막는 기능.
만약 lock 이 없다면 데이터의 일관성이 깨집니다.

        A session            B session
        (C##SCOTT)           (C##SCOTT)
1. update emp
 set sal = 9000
 where ename='KING';
                            2. update emp
                                 set sal = 0
                                 where ename = 'KING';
                                 commit;
3. select ename, sal
   from emp;
   -> 0 으로 보임

2 의 결과가 반영되지 않게 하기 위해서 행(rows) 에 lock 을 건다. (행 전체에!)


왼쪽 먼저 실행되고, 자동으로 lock 걸려서 오른쪽 실행 안됨
-> 왼쪽 commit 하고 나니까 오른쪽 lock 풀려서 실행됨!

lock 홀더와 lock watier 찾는 쿼리문

select decode(status,'INACTIVE',username || ' ' || sid || ',' || serial#,'lock') as Holder,
       decode(status,'ACTIVE',  username || ' ' || sid || ',' || serial#,'lock') as waiter, sid, serial#, status
    from( select level as le, NVL(s.username,'(oracle)') AS username,
    s.osuser,   
    s.sid,
    s.serial#,
    s.lockwait,
    s.module,
    s.machine,
    s.status,
    s.program,
    to_char(s.logon_TIME, 'DD-MON-YYYY HH24:MI:SS') as logon_time
       from v$session s
      where level>1
                or EXISTS( select 1
    from v$session
    where blocking_session = s.sid)
      CONNECT by PRIOR s.sid = s.blocking_session
  START WITH s.blocking_session is null);

LOCK 죽이기 (없애기)

alter system kill session '124,9709';

124 : sid번호
9709 : 시리얼번호
->
System KILL이(가) 변경되었습니다.

-> lock 풀린것 -> 테이블 볼려고 하면세션이 종료되었습니다 라고 뜸 (죽어버린것)
-> exit 하고 다시 sqlplus c##scott/tiger로 재접속 해야함 (dos창)

※ 우리가 테이블의 데이터를 update 하면 lock 이 행단위로 걸립니다.
그리고 반드시 db 에 데이터 수정 작업을 했으면 꼭 commit 을 해서
마무리를 잘 해야한다. 안그러면 다른 세션들이 lock에 걸리게 된다.

문제 479.
아래와 같이 c##scott 세션을 2개를 열고 update 를 수행하시오

      c##scott (A session)          c##scott (B session)
1. update emp                    
     set sal = 9000
     where job='SALESMAN';       2. update  emp
                                     set sal = 7000
                                     where ename='MARTIN';

martin 이 salesman 이므로 lock 걸려서 업데이트 안됨

문제 480.
이번에는 holder 를 죽이지 마시고 waiter 를 죽이세요
머가 홀더고 뭐가 웨이터..??

alter system kill session '616,41832' ;

※ lock 은 행단위로 걸리는것 이긴 하다.. 하지만 테이블 전체에 lock 걸수도 있음

문제 481. emp 테이블 전체에 lock 을 겁니다.

lock table emp in exclusive mode;

그 어떤것도 수정할 수 없음

LOCK 이 왜 필요한가?

데이터의 일관성이 깨지지 않기 위해서 필요하다.

문제 482. c##scott 유저로 3개의 세션을 열고 다음과 같이 update 하시오

기다리고있는 세션들.. 2,3 세션 (1 세션 commit 전) = enQueue (queue)
-> 1 세션이 commit 하고 나면 2는 빠져나온다 = deQueue

  • 선입선출 생각하면 될듯!! 먼저 들어간애가 먼저 나오는..?

084. SELECT FOR UPDATE 절 이해하기

LOCK 은 update 문을 수행할 때 update를 하려는 행들에 자동으로 lock이 걸리게 되는데
select 를 할 때도 lock 을 걸 수 있습니다.

보통은 select 를 할 때는 lock 이 안걸린다.

      A session                        B session
1. select ename, sal                  
     from ~~~
     where job='SALESMAN';       2. select ename, sal
                                     from ~~~~
                                     where ename='MARTIN';

이렇게 보통 select 는 lock 이 걸리지 않는다. 2가 작동된다 (단순 보는 것이기 때문)
그런데,
지금부터 특정 테이블의 데이터를 집계를 시작 해야하는데
그 누구도 내가 select 한 데이터를 수정못하게 해야한다면?

select ... for  update;

select for 문을 사용하면 된다!

      A session                        B session
1. select ename, sal                  
     from emp
     where job='SALESMAN'        2. update emp
     for update;                     set sal=0
                                     where ename='MARTIN';

이렇게 했을때 B는 아무 반응X (lock걸림)
A 에서 commit 하면 B 락 풀림!

문제 483. 위의 작업을 다시 한번 수행하고 sql developer 창에서
lock holder 와 lock waiter 를 확인하시오


에서도 죽일 수 있음 (sql 아니고 tool로 죽이는 방법)

마우스 오른쪽 눌러서 세션종료

확인해보면 죽었음

085. 서브쿼리를 사용하여 데이터 입력하기

예제. 아래의 테이블을 생성하시오

create table emp900
 (empno number(10),
  ename varchar2(10),
  sal   number(10) );

예제2. emp900 테이블에 아래의 데이터를 입력하시오
empno : 9384
ename : jack
sal : 3000

insert into emp900 (empno, ename, sal)
 values (9384, 'JACK', 3000)

서브쿼리 사용한 insert 문

예제3. 서브쿼리를 사용한 insert 문으로 사원 테이블의 직업이 'SALESMAN' 인 사원들의 사원번호, 이름, 월급을 emp900에 입력하시오

insert into emp900 (empno, ename, sal)
 select empno, ename, sal
 from emp
 where job='SALESMAN';
 
select * from emp900;
  • values 없이 select 문을 사용하면 됨

※ 위의 서브쿼리를 사용한 insert 문은 data 이행할 때 사용하는 SQL 입니다. (마이그레이션 = 데이터 옮길때)

테이블 구조만 생성하기

문제 484. 짝꿍의 data를 나의 db에 이행합니다.
짝꿍의 sales 데이터를 나의 db에 이행하기 위해서
먼저 sales 테이블의 구조를 생성합니다.

create table my_sales
 as
 select *
  from sh.sales
  where 1 = 2;

1=2 때문에 데이터는 못가져오고 테이블 구조만 생성

데이터 이행하기

문제 485. 짝꿍의 sales 테이블의 데이터를 나의 my_sales 테이블에 이행합니다.

insert into my_sales
 select *
   from sh.sales@dblink21;

select count(*) from my_sales;

086. 서브쿼리를 사용하여 데이터 수정하기

update 문에서 서브쿼리를 쓸 수 있는 절

update --> 서브쿼리 가능
set --> 서브쿼리 가능
where --> 서브쿼리 가능

(UPDATE) WHERE 서브쿼리

문제 486. 사원테이블에 ALLEN 보다 늦게 입사한 사원들의 월급을 9000으로 변경하시오

update emp
 set sal = 9000
 where hiredate > (select hiredate
                    from emp
                    where ename='ALLEN');

문제 487. SCOTT 과 같은 부서번호에서 일하는 사원들의 월급을 8000으로 수정하시오

update emp
 set sal = 8000
 where deptno = (select deptno
                  from emp
                  where ename='SCOTT');

(UPDATE) SET서브쿼리

문제 488. KING의 월급을 ALLEN의 월급으로 변경하시오

 update emp
  set  sal = (ALLEN 의 월급 )
  where ename = 'KING' ;

'allen' 의 월급을 구하는 서브쿼리

update emp
 set  sal = ( select sal
                 from emp
                 where ename='ALLEN')
 where ename = 'KING' ;

문제 489. KING의 부서번호를 JAMES 의 부서번호로 변경하시오

update emp
 set deptno = ( select deptno
                  from emp
                  where ename='JANES')
 where ename = 'KING' ;

배운거라 그냥 해본거고, 주로 '상호관련서브쿼리' 사용함
update 옆의 메인 테이블이름이 서브쿼리의 where 절에 들어가게 하는 (?)

테이블 초기화

emp와 dept를 깔끔하게 새로 생성하시오
https://cafe.daum.net/oracleoracle/Sdyr/846

컬럼 추가하기 (alter ~ add)

문제 490.
emp테이블에 loc컬럼을 추가하시오

alter table emp
 add loc varchar2(10);

상호관련 서브쿼리

문제 491. 지금 추가한 loc 컬럼에 해당 사원의 부서위치로 값을 갱신하시오
(merge 문 말고 상호관련 서브쿼리 를 이용한 update 문으로 수행)

update emp e
 set loc = (select loc
             from dept d
             where d.deptno = e.deptno);


emp e 데이터 가 서브쿼리 안으로 하나씩 들어와서 계산되는것

※ emp 테이블의 부서번호가 서브쿼리의 set절의 서브쿼리에 하나씩 들어가면서
하나씩 갱신하기 때문에 시간이 오래걸린다.
-> merge 문으로 하는게 시간이 훨씬 빠르다.

alter table emp
drop column loc;
(컬럼 드랍 시키는 sql)

문제 492.
사원테이블에 deptavg (부서평균) 라는 컬럼을 추가하시오

alter table emp
 add deptavg number (10,2);

전체 숫자 10자리, 소숫점은 2자리까지 허용

문제 493.
deptavg 컬럼에 값을 갱신하는데, 해당 사원이 속한 부서번호의 평균 월급으로 값을 갱신하시오

update emp e
 set deptavg = (select avg(sal)
                  from emp s
                  where s.deptno = e.deptno) ;

악성 sql 이긴 하다..

문제 494. (위의 답 튜닝하기!!)
위의 SQL을 튜닝하시오 (merge 문으로 수정하시오)

merge into EMP e
using ( select deptno, avg(sal) as 부서평균
            from emp
            group by deptno ) v
 on (e.deptno = v.deptno )
 when matched then
 update set e.deptavg = v.부서평균


여러번 튜닝하지않고 툭!

문제 495.
emp 테이블에 grade 컬럼을 추가하시오

alter table emp
 add grade number(10);

문제 496.
salgrade 테이블을 사용하여 emp 테이블의 grade 컬럼을 merge 하는데
해당사원의 급여등급으로 값을 merge 하시오 (튜닝후)

merge into emp e
 using salgrade s
  on (e.sal between s.losal and s.hisal)
  when matched then
  update set e.grade = s.grade;

문제 497.
위의 merge 문을 상호관련 서브쿼리를 사용한 update 문으로 작성하시오 (튜닝전)

update emp e
 set grade = (select grade
                from salgrade s
                where e.sal between s.losal and s.hisal);

문제 498.
merge 문이 튜닝 후 SQL임을 증명하기 위해서 대용량 테스트 테이블을 다음과 같이 생성하시오

create  table  sales100
as
 select rownum as num, amount_sold
 from sales;

실습 환경만들기

create table sales100
as
 select *
  from  sh.sales;
  -> sales100 이라는 테이블을 만드는데 내용을 sh.sales 에서 가져와서 만든다!

create table sales200
as
 select rownum rn, prod_id, cust_id, time_id, channel_id,
           promo_id, quantity_sold, amount_sold
  from sales100;
  -> sales200 테이블을 만드는데 select에 있는 컬럼들만 만든다
     데이터는 sales100 에서 가져온다!

alter table sales200
 add date_id date;
  -> sales200에 컬럼을 추가한다. 컬럼명은 date_id (내용은 비어있다)

create table time2
 ( rn number(10),
   date_id  date );
  -> time2 라는 테이블을 만드는데, rn 컬럼과 (숫자형태10자리), date_id (날짜형태) 라는 컬럼을 만든다. 내용은 비어있음


begin
  for i in  1 .. 918843  loop
     insert into time2
        values( i  , to_date('1961/01/02','YYYY/MM/DD')+ i );
   end loop;
end;
/
 -> 이런내용을 time2 에 넣을건데, 너무 많으니까 loop 걸어서 내용 넣어주겠음


commit;

time2 의 date_id 로 sales200에 갱신하기
sales200 의 time_id는 비어있는 상태 (컬럼만 만들어져있음)
rn 도 테이블명


문제 499. 튜닝 후 (merge)
time2 테이블을 사용하여 sales200 테이블을 merge 하는데,
time2 의 time_id 로 sales200 의 time_id를 갱신하시오.

merge into sales200
  using time2 t
  on (s.rn = t.rn)
  when matched then
   update set s.date_id=t.date_id;

set timing on -> 시간을 보는 문법

경과시간 보는 문법

set timing on

문제 500. (오늘의 마지막 문제)
위의 SQL의 튜닝전 SQL을 작성하시오
상호관련 서브쿼리를 이용한 update문으로 작성하시오

profile
열씨미하자

0개의 댓글