<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>not-mini.log</title>
        <link>https://velog.io/</link>
        <description>성장하는 개발자</description>
        <lastBuildDate>Thu, 05 Oct 2023 14:44:11 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>not-mini.log</title>
            <url>https://images.velog.io/images/not-mini/profile/9b9781e1-830e-4c0a-967f-87db2e6f1c36/C L O U D.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. not-mini.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/not-mini" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[C++ 파일 소스을(를) 열 수 없습니다. "stdafx.h"]]></title>
            <link>https://velog.io/@not-mini/C-%ED%8C%8C%EC%9D%BC-%EC%86%8C%EC%8A%A4%EC%9D%84%EB%A5%BC-%EC%97%B4-%EC%88%98-%EC%97%86%EC%8A%B5%EB%8B%88%EB%8B%A4.-stdafx.h</link>
            <guid>https://velog.io/@not-mini/C-%ED%8C%8C%EC%9D%BC-%EC%86%8C%EC%8A%A4%EC%9D%84%EB%A5%BC-%EC%97%B4-%EC%88%98-%EC%97%86%EC%8A%B5%EB%8B%88%EB%8B%A4.-stdafx.h</guid>
            <pubDate>Thu, 05 Oct 2023 14:44:11 GMT</pubDate>
            <description><![CDATA[<p>Visual Studio 2019</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/2e598243-b5e3-4aca-a58b-96117a8b182b/image.png" alt=""></p>
<ul>
<li>문제 : 콘솔 앱 프로젝트 생성 후 &#39;미리 컴파일된 헤더&#39; 사용 옵션만 변경하니 오류 발생</li>
</ul>
<p><img src="https://velog.velcdn.com/images/not-mini/post/0020bf6d-bc15-4e63-887e-c3602031cce2/image.png" alt=""></p>
<ul>
<li><p>원인
사용한다고 명시만 하고, 해당 파일이 추가되어 있지 않아, 파일을 못 찾으니 발생하는 에러</p>
</li>
<li><p>해결</p>
<ul>
<li>단순히 설정 변경만으로 해당 헤더 파일이 생성되는 것은 아니고, pch.h 파일을 생성한 후 미리 컴파일할 대상 목록을 #include로 명시</li>
<li>또는 콘솔 앱 프로젝트 생성이 아닌, Window 데스크톱 마법사 프로젝트 생성으로 하여, 초기 설정 탭에서 미리 컴파일된 헤더 추가를 선택
&lt;- 여기서는 &#39;stdafx.h&#39;가 아닌 pch.h 파일 생성됨</li>
</ul>
</li>
</ul>
<p><a href="https://gdnn.tistory.com/159">https://gdnn.tistory.com/159</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA['javac'은(는) 내부 또는 외부 명령 실행할 수 있는 프로그램 또는 배치 파일이 아닙니다]]></title>
            <link>https://velog.io/@not-mini/JDK-%EC%84%A4%EC%B9%98-%EC%98%A4%EB%A5%98</link>
            <guid>https://velog.io/@not-mini/JDK-%EC%84%A4%EC%B9%98-%EC%98%A4%EB%A5%98</guid>
            <pubDate>Tue, 12 Sep 2023 14:17:38 GMT</pubDate>
            <description><![CDATA[<p>jdk 설치 -&gt; 환경변수 설정 -&gt; cmd 명령어 확인</p>
<p>javac -version</p>
<p>없는 명령어라는 오류가 나와서</p>
<p>환경변수 설정 확인....</p>
<p>Path 설정 창 편집 버튼을 눌렀더니
모든 변수가 ;로 연달아서 한번에 나오는 오류...? 발생</p>
<p>거기서 JAVA_HOME\bin 변수 설정 부분을 봤더니</p>
<p>&quot;%JAVA_HOME%\bin&quot;; 로 확인되어서</p>
<p>&quot;&quot;를 지웠더니 오류 해결.... &quot;&quot;을 작성한 적은 없었는데..?</p>
<p>javac, java 정상 실행 완료</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/e2806461-0b9d-49c9-9ac7-6228da88d531/image.png" alt="완료 화면"></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ORACLE] pfile/ spfile]]></title>
            <link>https://velog.io/@not-mini/ORACLE-pfile-spfile</link>
            <guid>https://velog.io/@not-mini/ORACLE-pfile-spfile</guid>
            <pubDate>Sat, 08 Jul 2023 06:42:26 GMT</pubDate>
            <description><![CDATA[<p>startup 시에 오라클 엔진이 읽어들이는 파라미터 파일 우선순위</p>
<ol>
<li>spfile</li>
<li>pfile</li>
<li>...?</li>
</ol>
<p>파일 위치는 아래로 공통됨</p>
<p>$ORACLE_HOME/dbs</p>
<p>해당 위치에 spfile이 없으면, pfile을 읽어들이며 startup 됨</p>
<p>임의로 강제하여 읽어들이는 파일을 지정할 수 있음</p>
<pre><code>startup pfile=&#39;pfile 파일 경로&#39;</code></pre><h3 id="기동-시에-적용된-파라미터-파일-확인">기동 시에 적용된 파라미터 파일 확인</h3>
<p>show parameter spfile</p>
<p>해당 값이 있으면 : spfile
해당 값이 없으면 : pfile</p>
<h2 id="정적-파라미터--동적-파라미터">정적 파라미터 / 동적 파라미터</h2>
<p>정적 파라미터 : 재기동하지 않아도 즉각 반영되는 파라미터
동적 파라미터 : 변경시에 재기동을 필요로 하는 파라미터</p>
<pre><code>SELECT name, value, issys_modifiable FROM V$PARAMTER;</code></pre><p>issys_modifiable</p>
<ul>
<li>immediate : alter sytem 명령어로 바로 변경되는 </li>
<li>deferred : alter sytem 명령어로 변경이 되지만, 적용은 다음에 접속되는 세션부터 (session 관련 파라미터)</li>
<li>false : spfile을 변경해야 적용되는 파라미터 (반영시에 재기동 필요)</li>
</ul>
<h2 id="pfile">pfile</h2>
<p>DBA가 임의로 설정하는 파라미터 값</p>
<p>파일명 : initSID.ora</p>
<h2 id="spfile">spfile</h2>
<p>오라클 엔진에서 설정하는 파라미터 값</p>
<p>파일명 : spfileSID.ora</p>
<h2 id="파라미터-수정-명령어">파라미터 수정 명령어</h2>
<pre><code>alter system set parameter=&lt;변경값&gt; scope=&lt;both|memory|spfile&gt; ;</code></pre><p>spfile : spfile만 수정
memory : 현재 DB에만 적용이 되며, 재기동하면 설정값이 초기화되므로 
정적 파라미터는 memory 옵션으로 변경 불가 (ORA-02095; 지정된 초기화 파라미터는 변경될 수 없습니다)
both : spfile, memory 모두 변경됨 (default 설정)    </p>
<p>위 명령어로 수정시에, 동적 파라미터만 바로 반영이 된다.
정적 파라미터는 재기동시에만 변경되는 파라미터.</p>
<h2 id="spfile-to-pfile">spfile to pfile</h2>
<pre><code>create pfile from spfile;</code></pre><h2 id="pfile-to-spfile">pfile to spfile</h2>
<pre><code>create spfile from pfile;</code></pre><h2 id="변경여부-확인">변경여부 확인</h2>
<p>V$SPARAMETER : spfile 변경 여부 확인
show parameter or V$PARAMETER : 현재 DB 변경 여부 확인</p>
<pre><code>SELECT name, value FROM V$PARAMETER;</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[ORACLE] PL/SQL]]></title>
            <link>https://velog.io/@not-mini/ORACLE-PLSQL</link>
            <guid>https://velog.io/@not-mini/ORACLE-PLSQL</guid>
            <pubDate>Mon, 05 Jun 2023 07:39:00 GMT</pubDate>
            <description><![CDATA[<h2 id="plsqlprocedural-language-extention-to-sql">PL/SQL(Procedural Language extention to SQL)</h2>
<p>아래와 같은 절차적 언어의 요소를 더하여 향상된 데이터 처리를 가능케 함.</p>
<ul>
<li>선택처리(IF)</li>
<li>반복처리(LOOP, WHILE, FOR)</li>
</ul>
<h3 id="plsql의-구성">PL/SQL의 구성</h3>
<p>DECLARE ~ BEGIN ~ EXCEPTION ~ END;</p>
<ul>
<li>선언부 (DECLARE)</li>
<li>실행부 (BEGIN) </li>
<li>예외처리부 (EXCEPTION)</li>
</ul>
<p>CREATE PROCEDURE/FUNCTION : 저장 프로시저 혹은 함수 생성</p>
<h2 id="프로시저와-함수의-구분--모듈이-반환하는-값의-수에-의해-결정">프로시저와 함수의 구분 : 모듈이 반환하는 값의 수에 의해 결정</h2>
<p>함수 : 반환되는 값의 수가 하나
프로시저 : 반환되는 값의 수가 여러개</p>
<p>패키지 : 프로시저/함수의 그룹화</p>
<p>SQL&gt; @---.sql -- 프로시저 생성 (에러가 없으면 생성 완료)</p>
<p>프로시저 디버깅은 DB TOOL을 사용하여 가능함 (SQL Developer)</p>
<p>SQL&gt; execute 프로시저명(매개변수); -- 프로시저 실행</p>
<p>CREATE PROCEDURE TEST1
      (v_sub_name in varchar2(30)</p>
<p>is</p>
<h2 id="변수-선언">변수 선언</h2>
<p>variable_name {mode} data_type</p>
<p>자체 사용 변수 선언 시, mode는 생략</p>
<p>IS 이전 변수 선언 : 매개변수 선언 (호출 시 입력받는 값)
IS 이후 변수 선언 : 모듈에서만 사용되는 변수 (자체 사용 변수)</p>
<p>mode</p>
<ul>
<li>IN : 프로시저가 호출될 때 전달되는 변수</li>
<li>OUT : 프로시저 실행 후 반환되는 변수</li>
<li>INOUT : 2개의 기능을 모두 갖는 변수</li>
</ul>
<p>저장 프로시저의 경우, 테이블의 열의 값을 저장하게 됨으로 열의 데이터 타입을 참조하여 선언이 가능함</p>
<ul>
<li>%TYPE : 열의 데이터 타입을 참조</li>
</ul>
<p>v_sub_no  enrol.sub_no%type -- 열의 값들을 저장하는 변수 선언</p>
<ul>
<li>%ROWTYPE : 테이블의 모든 열의 데이터 타입을 참조</li>
</ul>
<p>v_enrol  enrol%rowtype -- 전체열을 모두 정의하는 변수 선언</p>
<p>ex) 열의 값 참조시</p>
<p>v_enrol.sub_no</p>
<p>실무에서는 스칼라타입(직접 데이터 타입 선언)의 변수보다는 참조타입 변수를 많이 사용함</p>
<h3 id="선택-처리문">선택 처리문</h3>
<p>if 조건1 then
   실행문1;
else if 조건문2 then
   실행문2;
else
   실행문
end if;</p>
<h3 id="반복-처리문">반복 처리문</h3>
<p>1) LOOP ~ END LOOP (반복 횟수를 정할 수 없을 때)
반복을 중단하는 조건문 주의 (무한반복)</p>
<p>LOOP
   실행문1;
   EXIT WHEN 반복 중단 조건문;
END LOOP; </p>
<p>2) FOR ~ LOOP (반복 횟수 지정)
[REVERSE]로 증분값을 감소하는 방안으로 사용가능함</p>
<p>FOR 변수 IN 초기값..최종값 LOOP
   실행문;
END LOOP;</p>
<p>예제는 아래와 같다.</p>
<p>FOR v_cnt IN 1..10 LOOP
   .......
END LOOP</p>
<p>3)WHILE ~ END LOOP (조건이 만족되는 동안 반복실행)</p>
<p>WHILE 반복 조건
   실행문;
END LOOP;</p>
<h2 id="저장-프로시저-작성-sql">저장 프로시저 작성 (.sql)</h2>
<p>CREATE [OR REPLACE] PROCEDURE 스키마.프로시저명
(
   매개변수명 [MODE] DATA_TYPE,
   ..........
)
IS 
   변수명 DATA_TYPE,
   ..........
BEGIN
   ~
EXCEPTION
   ~
END;
/</p>
<p>예제)</p>
<p>CREATE OR REPLACE PROCEDURE test3
(v_stu_no  in  student.stu_no%type,
 v_stu_name   out  student.stu_name%type)
IS
BEGIN
    SELECT stu_name
    INTO v_stu_name
    FROM student
    WHERE  stu_no = v_stu_no;</p>
<p>END test3;
/</p>
<p>SQL&gt; @test3.sql
SQL&gt; variable d_stu_name varchar2(12); -- 바인드 변수 선언
SQL&gt; excute test3(20153075, :d_stu_name); -- :d_stu_name
SQL&gt; print d_stu_name;</p>
<h2 id="저장-함수-작성">저장 함수 작성</h2>
<p>CREATE [OR REPLACE] FUNCTION 스키마.함수명
( 매개변수명1 [mode] data_type,
    ..............)
    return   data_type      --- 반환 데이터의 자료형 정의
IS
   variable data_type,
   ............
BEGIN
   ........
   RETURN variable;
EXCEPTION
   ........
END;</p>
<p>저장 함수를 실행하고 돌아갈 때 하나의 값을 가지게 되며, 이 값은 함수의 이름에 저장됨
따라서, 함수의 이름에 반환 데이터를 저장하기 위한 데이터 타입이 필요함</p>
<p>   return   data_type;</p>
<p>예제)</p>
<p>CREATE OR REPLACE FUNCTION test6
  (v_enr_grade in number)
  return      char
IS 
  enr_score   char
BEGIN
   IF v_enr_grade &gt;= 90 then enr_score := &#39;A&#39;;
   ELSE IF v_enr_grade &gt;= 80 then enr_score := &#39;B&#39;;
   ELSE IF v_enr_grade &gt;= 70 then enr_score := &#39;C&#39;;
   ELSE IF v_enr_grade &gt;= 60 then enr_score := &#39;D&#39;;
   ELSE enr_score := &#39;F&#39;;
   END IF;
   RETURN (enr_score);
END test6;
/</p>
<p>SQL&gt; @test6.sql
SQL&gt; variable d_score char;
SQL&gt; excute :d_score := test6(95);
SQL&gt; print d_score;</p>
<p>SQL&gt; select enr_grade, test6(enr_grade) as score
     from enrol
     where stu_no = &#39;20131001&#39;;</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[MySQL] 계정 관리]]></title>
            <link>https://velog.io/@not-mini/MYSQL-%EB%AA%85%EB%A0%B9%EC%96%B4</link>
            <guid>https://velog.io/@not-mini/MYSQL-%EB%AA%85%EB%A0%B9%EC%96%B4</guid>
            <pubDate>Sat, 27 May 2023 11:46:03 GMT</pubDate>
            <description><![CDATA[<h3 id="계정-목록-조회">계정 목록 조회</h3>
<p><strong>select user, host from mysql.user order by 1,2;</strong></p>
<h3 id="계정-생성">계정 생성</h3>
<p><strong>CREATE USER</strong> <code>[계정명]</code>@<code>[접속 IP]</code> <strong>IDENTIFIED BY</strong> <code>[비밀번호]</code>;</p>
<h3 id="권한-부여">권한 부여</h3>
<p><strong>GRANT</strong> <code>{권한}</code> <strong>ON</strong> <code>{테이블명}</code> <strong>TO</strong> <code>{계정}</code>;</p>
<p>EX ) </p>
<p>GRANT SELECT, PROCESS, SHOW DATABASES, SHOW VIEW ON <em>.</em> TO <code>[계정명]</code>@<code>[IP]</code>;</p>
<h3 id="계정-권한-조회">계정 권한 조회</h3>
<p><strong>show grants for</strong> &#39;{계정}&#39;;</p>
<h3 id="생성-암호화된-비밀번호로-계정-생성">생성 암호화된 비밀번호로 계정 생성</h3>
<p>Mysql 8.0 </p>
<p><strong>CREATE USER</strong> <code>[계정명]</code>@<code>[IP]</code> *<em>identified with mysql_native_password as *</em>&#39;*77B368A87EAD78B0629FC94070814833DAAADE0A&#39;;</p>
<h3 id="변경비밀번호-시도-횟수-초과되었을-때">변경비밀번호 시도 횟수 초과되었을 때</h3>
<p>계정 lock 해제</p>
<p>ALTER USER <code>[계정명]</code> account unlock;</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[실무에서 바로 쓰는 SQL 튜닝][ORACLE] 28강]]></title>
            <link>https://velog.io/@not-mini/%EC%8B%A4%EB%AC%B4%EC%97%90%EC%84%9C-%EB%B0%94%EB%A1%9C-%EC%93%B0%EB%8A%94-SQL-%ED%8A%9C%EB%8B%9DORACLE-28%EA%B0%95</link>
            <guid>https://velog.io/@not-mini/%EC%8B%A4%EB%AC%B4%EC%97%90%EC%84%9C-%EB%B0%94%EB%A1%9C-%EC%93%B0%EB%8A%94-SQL-%ED%8A%9C%EB%8B%9DORACLE-28%EA%B0%95</guid>
            <pubDate>Sat, 20 May 2023 01:18:21 GMT</pubDate>
            <description><![CDATA[<p><strong>인덱스 스캔 방법 7가지</strong></p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/cb3f3f39-da80-4ed9-86cc-609ea7ea2697/image.png" alt="인덱스 스캔 방법"></p>
<h2 id="index-range-scan---숫자형-컬럼-인덱스">INDEX RANGE SCAN - 숫자형 컬럼 인덱스</h2>
<p>INDEX RANGE SCAN : 
인덱스에서 조건과 일치하는 행을 찾았을 때에, 바로 스캔을 멈추지 않고 아래의 행까지 스캔하는 것</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/d62ff3fe-4e6f-4435-9a16-66b9001a9fbb/image.png" alt="INDEX RANGE SCAN"></p>
<p>만약 조건절이 UNIQUE 제약 조건(행의 값이 유일무이)이 걸려있다면, INDEX RANGE SCAN을 하지 않음</p>
<ul>
<li>하나만 스캔함</li>
</ul>
<p>인덱스가 있음에도 불구하고 FULL TABLE SCAN을 한다면, 아래와 같이 힌트를 명시한다</p>
<p><strong>INDEX SCAN : /<em>+index(테이블명 인덱스명)</em>/</strong> </p>
<p>select <strong>/<em>+index(emp emp_sal)</em>/</strong> ename, sal
from emp
where sal = 1600;</p>
<h2 id="index-range-scan---중복된-데이터가-있는-컬럼">INDEX RANGE SCAN - 중복된 데이터가 있는 컬럼</h2>
<p>중복된 값을 가지는 칼럼에 대해선 CREATE UNIQUE INDEX가 안됨</p>
<p>CREATE INDEX emp_job
ON emp(job);</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/e135f70b-4c39-442e-ae3f-c7528163a891/image.png" alt="중복된 데이터 인덱스 레인지 스캔"></p>
<p>일치하는 행들을 연달아서 스캔하다가, 일치하지 않는 값을 만나면 스캔을 멈추고 rowid로 table access를 함</p>
<h1 id="이럴때는-where절의-좌변을-가공하지-마라">이럴때는 where절의 좌변을 가공하지 마라</h1>
<h2 id="where절의-인덱스-칼럼이-가공되었다면">where절의 인덱스 칼럼이 가공되었다면</h2>
<p><img src="https://velog.velcdn.com/images/not-mini/post/c5a5f095-ed68-4a79-9739-977cf70a9b1f/image.png" alt="튜닝 전 예시"></p>
<p>인덱스 칼럼을 가공하지 말아라</p>
<p>인덱스 컬럼을 가공하여 조건을 걸게 되면, 인덱스 테이블 access를 하지 못하고 full table scan을 하게 됨</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/9235aeef-f09e-426d-ac1d-2d2c93740e3e/image.png" alt="튜닝 후 예시"></p>
<p>문자형 칼럼예시 </p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/f454741e-effa-4be4-b714-4917215a12db/image.png" alt="튜닝 전 예시"></p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/c87450a9-1753-442f-bf85-08e3003bd271/image.png" alt="튜닝 후 예시"></p>
<p>날짜형 칼럼예시</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/f8528aba-565b-44da-8d53-95c4013d3272/image.png" alt="튜닝 전 예시"></p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/a263c543-590f-4580-b584-deee64140cfb/image.png" alt="튜닝 후 예시"></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[실무에서 바로 쓰는 SQL 기본과 SQL 튜닝][ORACLE] 25강]]></title>
            <link>https://velog.io/@not-mini/%EC%8B%A4%EB%AC%B4%EC%97%90%EC%84%9C-%EB%B0%94%EB%A1%9C-%EC%93%B0%EB%8A%94-SQL-%EA%B8%B0%EB%B3%B8%EA%B3%BC-SQL-%ED%8A%9C%EB%8B%9DORACLE-25%EA%B0%95-yp2kf83q</link>
            <guid>https://velog.io/@not-mini/%EC%8B%A4%EB%AC%B4%EC%97%90%EC%84%9C-%EB%B0%94%EB%A1%9C-%EC%93%B0%EB%8A%94-SQL-%EA%B8%B0%EB%B3%B8%EA%B3%BC-SQL-%ED%8A%9C%EB%8B%9DORACLE-25%EA%B0%95-yp2kf83q</guid>
            <pubDate>Sat, 20 May 2023 01:17:52 GMT</pubDate>
            <description><![CDATA[<h2 id="최대-공약수-구하기">최대 공약수 구하기</h2>
<p>SELECT 16 NUM1, 24 NUM2
FROM DUAL;</p>
<p>WITH NUM_D AS ( SELECT 16 NUM1, 24 NUM2
                FROM DUAL; )
SELECT LEVEL, MOD(NUM1, LEVEL), MOD(NUM2, LEVEL)
FROM NUM_D
CONNECT BY LEVER &lt;= NUM2;</p>
<p>WITH NUM_D AS ( SELECT 16 NUM1, 24 NUM2
                FROM DUAL; )
SELECT LEVEL, MOD(NUM1, LEVEL), MOD(NUM2, LEVEL)
FROM NUM_D
WHERE MOD(NUM1, LEVEL) = 0
AND MOD(NUM2, LEVEL) = O
CONNECT BY LEVER &lt;= NUM2;</p>
<p>WITH NUM_D AS ( SELECT 16 NUM1, 24 NUM2
                FROM DUAL; )
SELECT MAX(LEVEL) AS &quot;최대 공약수&quot;
FROM NUM_D
WHERE MOD(NUM1, LEVEL) = 0
AND MOD(NUM2, LEVEL) = O
CONNECT BY LEVER &lt;= NUM2;</p>
<p>ACCEPT P_N1 PROMPT &#39; 첫번째 숫자를 입력하시오.&#39;;
ACCEPT P_N2 PROMPT &#39; 두번째 숫자를 입력하시오.&#39;;</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/24e8686c-295c-4d5f-b798-92348d840fa9/image.png" alt="프롬프트 예제"></p>
<p>WITH NUM_D AS ( SELECT 16 NUM1, 24 NUM2
                FROM DUAL; )
SELECT NUM1, NUM2, (NUM1/MAX(LEVEL))* (NUM2/MAX(LEVEL)) * MAX(LEVEL) AS &quot;최소 공배수&quot;
FROM NUM_D
WHERE MOD(NUM1, LEVEL) = 0
AND MOD(NUM2, LEVEL) = O
CONNECT BY LEVER &lt;= NUM2;</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[실무에서 바로 쓰는 SQL 기본과 SQL 튜닝][ORACLE] 27강]]></title>
            <link>https://velog.io/@not-mini/%EC%8B%A4%EB%AC%B4%EC%97%90%EC%84%9C-%EB%B0%94%EB%A1%9C-%EC%93%B0%EB%8A%94-SQL-%EA%B8%B0%EB%B3%B8%EA%B3%BC-SQL-%ED%8A%9C%EB%8B%9DORACLE-27%EA%B0%95</link>
            <guid>https://velog.io/@not-mini/%EC%8B%A4%EB%AC%B4%EC%97%90%EC%84%9C-%EB%B0%94%EB%A1%9C-%EC%93%B0%EB%8A%94-SQL-%EA%B8%B0%EB%B3%B8%EA%B3%BC-SQL-%ED%8A%9C%EB%8B%9DORACLE-27%EA%B0%95</guid>
            <pubDate>Sat, 20 May 2023 01:17:26 GMT</pubDate>
            <description><![CDATA[<h2 id="sql의-실행계획">SQL의 실행계획</h2>
<p>SQL문을 실행하기 전에 내부적으로 생성한 SQL 실행 계획</p>
<ol>
<li><p>PARSER : 사용자의 SQL문이 문제가 있는지를 확인</p>
</li>
<li><p>OPTIMIZER</p>
</li>
</ol>
<p>1) RULE-BASED OPTIMIZER (RBO) : 오라클의 우선 순위에 따라 실행계획 생성
2) <strong>COST-BASED OPTIMIZER (CBO)</strong> : 비용이 적게드는 방법으로 실행계획 생성 (융통성 있게) - ORACLE DEFAULT</p>
<p>CBO이기 때문에 SQL 튜닝이 필요함 - 그때그때 실행 성능이 달라짐</p>
<ol start="3">
<li><p>ROW SOURCE GENERATOR : 플랜을 완성</p>
</li>
<li><p>SQL EXECUTION : 실행 계획에 따라서 SQL문 실행</p>
</li>
</ol>
<p><img src="https://velog.velcdn.com/images/not-mini/post/3b352a03-74e7-418d-b097-fb9acce89ae4/image.png" alt="순서도"></p>
<h2 id="예상-실행계획">예상 실행계획</h2>
<p>SQL문을 실행하기 전에 만든 예상 계획</p>
<p>SQL문 전에 &#39;EXPLAIN PLAN FOR&#39;을 작성하여 실행</p>
<p>EXPLAIN PLAN FOR
SELECT ename, sal
FROM emp
WHERE sal = 1300;</p>
<p>SELECT * FROM TABLE(dbms_xplan.display); -- 예상 실행계획 확인 가능</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/e7c841af-41bf-472f-b88c-16b9dc01a56a/image.png" alt="결과"></p>
<p>안쪽에서 바깥 순서로 읽으면 됨 - 1,0 순서</p>
<h2 id="실제-실행계획">실제 실행계획</h2>
<p>SQL문을 실행할 때 사용했던 실행계획</p>
<p>SELECT /*+ GATHER_PLAN_STATISTICS */ ENAME, SAL
FROM EMP
WHERE SAL=1300;</p>
<p>/<em>+ GATHER_PLAN_STATISTICS */
/</em>+ .... */  : 힌트 </p>
<p>SELECT *
FROM TABLE(dbms_xplan.display_cursor(null,null,&#39;ALLSTATS LAST&#39;));</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/22fa5c53-acd9-4c77-be2b-9564b4f16c1f/image.png" alt="결과"></p>
<p>E-ROWS/A-ROWS : 예상 행 수, 실제 행 수
A-TIME : 수행 시간
<strong>BUFFERS : 수행하기 위해 읽어들인 오라클 메모리의 수</strong> -- 수가 작을수록 성능이 좋은 SQL문</p>
<p>예상 실행계획과 다르게 실제 실행계획에서는 <strong>버퍼의 수</strong>를 확인할 수 있다</p>
<h2 id="힌트">힌트</h2>
<p>SQL을 실행할 때 옵티마이저로 하여금 힌트대로 실행계획을 생성해달라고 주문</p>
<p>SELECT /*+ GATHER_PLAN_STATISTICS FULL(EMP) */ ENAME, SAL
FROM EMP
WHERE SAL=1300;</p>
<p>FULL(EMP) : EMP 테이블을 FULL SCAN하라
GATHER_PLAN_STATISTICS : 실제 실행계획을 보여라</p>
<h3 id="인덱스를-생성했을-때">인덱스를 생성했을 때</h3>
<p>CREATE INDEX emp_sal
ON emp(sal);</p>
<p>SELECT /*+ GATHER_PLAN_STATISTICS INDEX(EMP EMP_SAL) */ ENAME, SAL
FROM EMP
WHERE SAL=1300;</p>
<p>INDEX(EMP EMP_SAL) : EMP_SAL이란 인덱스를 타서 EMP 테이블을 스캔하여라</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/7e56044e-fc25-4fbe-b5c7-42b07c8c20f6/image.png" alt="인덱스 사용 결과"></p>
<p>버퍼의 개수가 2개로 줄었음</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/9a61030e-599b-4824-b0d9-3725a4138810/image.png" alt="인덱스 미사용 결과"></p>
<p>조건에서 사용되는 칼럼에 인덱스를 생성한 후 실행하면, 성능이 좋아진다 (사용되는 버퍼의 수가 줄어든다)</p>
<h2 id="인덱스">인덱스</h2>
<p>쿼리문의 검색 속도를 높이는 DB OBJECT</p>
<p>인덱스는 컬럼값과 ROWID로 이루어져있고, 컬럼값은 ASCENDING하게 정렬되어 있음</p>
<p>숫자형 칼럼에 걸린 인덱스에 대한 인덱스 테이블을 출력</p>
<p>SELECT SAL, ROWID
FROM EMP; -- 테이블에서 값을 읽어옴</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/72c87cf5-f9bd-4d5f-8980-bfa124451c9b/image.png" alt="테이블"></p>
<p>SELECT SAL, ROWID
FROM EMP
WHERE SAL &gt;= 0; -- 인덱스 테이블을 출력함</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/52fdd802-5680-4cd9-8616-5d893a278976/image.png" alt="인덱스 테이블"></p>
<p>문자형 칼럼에 걸린 인덱스에 대한 인덱스 테이블을 출력</p>
<p>SELECT ENAME, ROWID
FROM EMP
WHERE ENAME &gt; &#39; &#39;; -- 인덱스 테이블 출력</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/16d06837-bf40-42e6-ac7d-771d22d34d3e/image.png" alt="인덱스 테이블"></p>
<p>실제 실행 계획을 출력해보면, 인덱스 테이블에서만 읽어왔다는 걸 알 수 있음</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/52b8ab34-65d5-4a8e-ae57-0925ef4abeb2/image.png" alt="실제 실행 계획"></p>
<p>문자형 칼럼에 걸린 인덱스에 대한 인덱스 테이블을 출력</p>
<p>SELECT HIREDATE, ROWID
FROM EMP
WHERE HIREDATE &lt; TO_DATE(&#39;9999/12/31&#39;,&#39;RRRR/MM/DD&#39;);</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/058f6cac-12c1-4d53-91b7-4d2af1f6472d/image.png" alt="인덱스 테이블"></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[실무에서 바로 쓰는 SQL 기본과 SQL 튜닝][ORACLE] 25강]]></title>
            <link>https://velog.io/@not-mini/%EC%8B%A4%EB%AC%B4%EC%97%90%EC%84%9C-%EB%B0%94%EB%A1%9C-%EC%93%B0%EB%8A%94-SQL-%EA%B8%B0%EB%B3%B8%EA%B3%BC-SQL-%ED%8A%9C%EB%8B%9DORACLE-25%EA%B0%95</link>
            <guid>https://velog.io/@not-mini/%EC%8B%A4%EB%AC%B4%EC%97%90%EC%84%9C-%EB%B0%94%EB%A1%9C-%EC%93%B0%EB%8A%94-SQL-%EA%B8%B0%EB%B3%B8%EA%B3%BC-SQL-%ED%8A%9C%EB%8B%9DORACLE-25%EA%B0%95</guid>
            <pubDate>Sat, 20 May 2023 01:16:53 GMT</pubDate>
            <description><![CDATA[<h2 id="빅데이터-분석">빅데이터 분석</h2>
<p>우리나라 남자들이 가장 많이 걸리는 암?</p>
<p>select *
from cancer
where 성 != &quot;남녀전체&quot; and 발생연도=&#39;1999&#39; and 발생자수 is not null and 암종 != &#39;모든암&#39; and 성=&#39;남자&#39;
order by 발생자수 desc fetch first 4 rowd only;</p>
<p>연설문을 오라클 테이블에 문장별로 저장</p>
<p>SELECT REGEXP_SUBSTR(&#39;I NEVER GRADUATED FROM COLLEGE&#39;, &#39;[^ ]+&#39;, 1, 2) word
from  dual;</p>
<p>해당 문장에서 공백이 아닌 어절 여러개([^ ])를 검색해서, 그중 첫번째부터 검색해서 두번째에 나오는 것을 출력</p>
<p>출력문을 어절 단위로 출력</p>
<p>select regexp_substr(lower(speech_text), &#39;[^ ]+&#39;, 1, a) word
from speech, (select level a
              from dual
              connect by level &lt;=52);</p>
<p>테이블(연설문) 전체 데이터 중에서 가장 많이 나온 단어 순서로 출력</p>
<p>select word, count(*)
from (
        select regexp_substr(lower(speech_text), &#39;[^ ]+&#39;, 1, a) word
        from speech, (select level a
                          from dual
                          connect by level &lt;=52)</p>
<pre><code>  )</code></pre><p>where word is not null
group by word
order by count(*) desc;</p>
<p>스피치 연설문 테이블을 어절로 나눈 결과를 뷰로 생성함</p>
<p>create or replace view speech_view
as
select regexp_substr(lower(speech_text), &#39;[^ ]+&#39;, 1, a) word
        from speech, (select level a
                          from dual
                          connect by level &lt;=52);</p>
<p>스피치 연설문 중에서 긍정단어와 일치하는 단어의 개수를 출력</p>
<p>select count(word) as 긍정단어
from speech_view
where lower(word) in (select lower(p_text)
                      from positive);</p>
<p>select *
from crime_day
unpivot (cnt for day_cnt in (sun_cnt, mon_cnt, tue_cnt, wed_cnt, thu_cnt, fri_cnt, sat_cnt));</p>
<p>unpivot : 칼럼과 행이 변환됨</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/cbe98a13-a736-4644-9301-19ff321f095f/image.png" alt="이전"></p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/3eaff232-83db-4c0f-a55c-8e3cdcf69b92/image.png" alt="이후"></p>
<p>절도 범죄에 대해서 가장 많이 발생한 요일별로 순위매겨서 출력</p>
<p>select day_cnt, cnt, rank() over (order by cnt desc) rnk
from crime_day_unpivot
where trim(crime_type) = &#39;절도&#39;;</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/323ed231-11ad-46c8-8858-c6cefa0d0ae2/image.png" alt="출력"></p>
<p>1위인 칼럼만 출력하고 싶으니, from절의 서브쿼리로 넣어야 함</p>
<p>select *
from (select day_cnt, cnt, rank() over (order by cnt desc) rnk
        from crime_day_unpivot
        where trim(crime_type) = &#39;절도&#39;
        )
where rnk = 1;</p>
<p>대학등록금이 비싼 순서대로 순위를 매겨서 출력</p>
<p>select university, tuition_fee, rank() over (order by tuition_fee desc nulls last) 순위
from university_fee;</p>
<p>select *
from (
    select university, tuition_fee, 
            rank() over (order by tuition_fee desc nulls last) 순위
    from university_fee;
)
where 순위 = 1;</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[실무에서 바로 쓰는 SQL 기본과 SQL 튜닝][ORACLE] 23강]]></title>
            <link>https://velog.io/@not-mini/%EC%8B%A4%EB%AC%B4%EC%97%90%EC%84%9C-%EB%B0%94%EB%A1%9C-%EC%93%B0%EB%8A%94-SQL-%EA%B8%B0%EB%B3%B8%EA%B3%BC-SQL-%ED%8A%9C%EB%8B%9DORACLE-23%EA%B0%95</link>
            <guid>https://velog.io/@not-mini/%EC%8B%A4%EB%AC%B4%EC%97%90%EC%84%9C-%EB%B0%94%EB%A1%9C-%EC%93%B0%EB%8A%94-SQL-%EA%B8%B0%EB%B3%B8%EA%B3%BC-SQL-%ED%8A%9C%EB%8B%9DORACLE-23%EA%B0%95</guid>
            <pubDate>Sat, 20 May 2023 01:16:25 GMT</pubDate>
            <description><![CDATA[<h2 id="구구단-2단-출력">구구단 2단 출력</h2>
<p>계층형 질의문 + with 절</p>
<p>with loop_table as (select level as num
                    from dual
                    connect by level &lt;= 9)
select &#39;2&#39; || &#39; x &#39;|| num || &#39; = &#39;|| 2*num as &quot;2단&quot;
from loop_table;</p>
<p>1번부터 100번까지의 합?</p>
<p>select sum(level)
from dual
connect by level &lt;= 100;</p>
<p>1번부터 100번까지의 합에서 55를 뺀 값?</p>
<p>select sum(level)
from dual
where level != 55
connect by level &lt;= 100;</p>
<h2 id="구구단-19단-출력">구구단 1~9단 출력</h2>
<p><img src="https://velog.velcdn.com/images/not-mini/post/59a7a704-3535-44d0-867c-d668929fccee/image.png" alt="예제"></p>
<p>with loop_table as (select level as num
                    from dual
                    connect by level &lt;= 9),
     gugu_table as (select level + 1 as gugu
                     from dual
                    connect by level &lt;= 8)
select to_char(a.num) || &#39; x &#39; || to_char(b.gugu) || &#39; = &#39; || to_char(b.gugu * a.num) as 구구단
from loop_table a, gugu_table b; -- 전체에 대해서 조인</p>
<p>2,5,7단만 빼고 출력</p>
<p>with loop_table as (select level as num
                    from dual
                    connect by level &lt;= 9),
     gugu_table as (select level as gugu
                     from dual
                    connect by level &lt;= 9)
select to_char(a.num) || &#39; x &#39; || to_char(b.gugu) || &#39; = &#39; || to_char(b.gugu * a.num) as 구구단
from loop_table a, gugu_table b
where a.num in (2,5,7);</p>
<h2 id="직각-삼각형-출력">직각 삼각형 출력</h2>
<p>with loop_table as (select level as num
                    from dual
                    connect by level &lt;= 8)
select lpad(&#39;<em>&#39;, num, &#39;</em>&#39;) as star
from loop_table;</p>
<p>반대로 출력하기</p>
<p>with loop_table as (select 9-level as num
                    from dual
                    connect by level &lt;= 8)
select lpad(&#39;<em>&#39;, num, &#39;</em>&#39;) as star
from loop_table;</p>
<h2 id="삼각형-출력">삼각형 출력</h2>
<p>with loop_table as (select level as num
                    from dual
                    connect by level &lt;=8)
select lpad(&#39; &#39;, 10-level, &#39; &#39;) || lpad(&#39;<em>&#39;, num, &#39;</em>&#39;) as &quot;Triangle&quot;
from loop_table;</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[실무에서 바로 쓰는 SQL 기본과 SQL 튜닝][ORACLE] 22강]]></title>
            <link>https://velog.io/@not-mini/%EC%8B%A4%EB%AC%B4%EC%97%90%EC%84%9C-%EB%B0%94%EB%A1%9C-%EC%93%B0%EB%8A%94-SQL-%EA%B8%B0%EB%B3%B8%EA%B3%BC-SQL-%ED%8A%9C%EB%8B%9DORACLE-22%EA%B0%95</link>
            <guid>https://velog.io/@not-mini/%EC%8B%A4%EB%AC%B4%EC%97%90%EC%84%9C-%EB%B0%94%EB%A1%9C-%EC%93%B0%EB%8A%94-SQL-%EA%B8%B0%EB%B3%B8%EA%B3%BC-SQL-%ED%8A%9C%EB%8B%9DORACLE-22%EA%B0%95</guid>
            <pubDate>Sat, 20 May 2023 01:16:08 GMT</pubDate>
            <description><![CDATA[<h2 id="with절-사용하기">WITH절 사용하기</h2>
<p>메인 쿼리와 서브 쿼리문을 실행할 때의 시간이 오래 걸릴 때에 사용함</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/88f4c02e-3566-4045-b360-58f1f7d10398/image.png" alt="109번"></p>
<pre><code>SELECT job, sum(sal)
FROM emp
GROUP BY job
having sum(sal) &gt; (select avg(sum(sal))
                    from emp
                    group by job);
</code></pre><p>20분(메인 쿼리) + 20분(서브 쿼리) = 40분</p>
<p>아래와 같이 작성하면, 실행 시간 단축 (동일한 결과)</p>
<pre><code>WITH job_subsal as (SELECT job, sum(sal) as 토탈
                    FROM emp
                    GROUP BY job)
SELECT job, 토탈
FROM job_subsal
WHERE 토탈 &gt; (SELECT avg(토탈)
                FROM job_subsal);</code></pre><p>job_subsal : 임시 테이블명 (as절의 select 결과를 job_subsal의 데이터로 함)</p>
<p>아래 쿼리문에서 사용된 후, 사라지는 테이블</p>
<p>with절에서 20분을 소요하고, 아래에서는 이미 생성된 테이블에 대해서 쿼리문을 실행하는 것이므로 빠르게 수행됨</p>
<p>with절을 너무 많이 남발하면, 디스크 공간에 많은 temp table이 생겨남... (주의)</p>
<p>부서번호별 토탈월급을 출력하는데 부서번호별 토탈월급들의 평균값보다 더 큰 것만 출력</p>
<p>with dept_sumsal as (select deptno, sum(sal) as sumsal
                    from emp
                    group by deptno)
select deptno, sumsal
from dept_sumsal
where sumsal &gt; (select avg(sumsal)
                from dept_sumsal);</p>
<h2 id="with절---subquery-factoring">WITH절 - SUBQUERY FACTORING</h2>
<p>FROM절 서브쿼리로는 구현할수 없는 부분을 구현 가능하게 함</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/a728353a-3f92-4083-baa8-a9da47ec58f1/image.png" alt=""></p>
<p>WITH job_sumsal as (select job, sum(sal) 토탈
                    from emp
                    group by job),
     deptno_sumsal as (select deptno, sum(sal) 토탈
                         from emp
                        group by deptno
                        having sum(sal) &gt; (select avg(토탈) + 3000
                                                from job_sumsal)</p>
<pre><code>                   )</code></pre><p>select deptno, 토탈
from deptno_sumsal;</p>
<p>입사한 년도와 입사한 년도별 토탈월급을 출력하는데 부서번호별 토탈월급들의 평균값보다 더 큰 것만 출력</p>
<p>with  deptno_sumsal as (select deptno, sum(sal) 토탈
                        from emp
                        group by deptno),
      hire_sumsal as (select to_char(hiredate,&#39;RRRR&#39;) hire_year, sum(sal) 토탈
                          from emp
                        group by to_char(hiredate,&#39;RRRR)
                        having sum(sal) &gt; (select avg(토탈)
                                            from deptno_sumsal)
                      )
select hire_year, 토탈
from hire_sumsal;</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[실무에서 바로 쓰는 SQL 기본과 SQL 튜닝][ORACLE] 20강]]></title>
            <link>https://velog.io/@not-mini/%EC%8B%A4%EB%AC%B4%EC%97%90%EC%84%9C-%EB%B0%94%EB%A1%9C-%EC%93%B0%EB%8A%94-SQL-%EA%B8%B0%EB%B3%B8%EA%B3%BC-SQL-%ED%8A%9C%EB%8B%9DORACLE-20%EA%B0%95</link>
            <guid>https://velog.io/@not-mini/%EC%8B%A4%EB%AC%B4%EC%97%90%EC%84%9C-%EB%B0%94%EB%A1%9C-%EC%93%B0%EB%8A%94-SQL-%EA%B8%B0%EB%B3%B8%EA%B3%BC-SQL-%ED%8A%9C%EB%8B%9DORACLE-20%EA%B0%95</guid>
            <pubDate>Sat, 20 May 2023 01:15:44 GMT</pubDate>
            <description><![CDATA[<h2 id="flashback-version-query">FLASHBACK VERSION QUERY</h2>
<p>변경 이력 확인</p>
<ol>
<li>COMMIT이 진행되어야 VERSION이 업데이트 됨</li>
<li>versions_starttime의 초기값은 null로 되어있으므로, null first를 order by절에 작성하면 순서대로 확인하기 용이함</li>
<li>to_timestamp 값은 특정 시점을 시작지점으로 설정할 수 있음
 between timestamp 구문에서 종료시점도 설정 가능함</li>
</ol>
<p><img src="https://velog.velcdn.com/images/not-mini/post/952e7d03-35b8-4989-ac0f-2b7b70d42261/image.png" alt="예제 102"></p>
<p>SELECT ename, sal, deptno, versions_starttime, versions_endtime, versions_operation
FROM emp
VERSIONS BETWEEN TIMESTAMP TO_TIMESTAMP(&#39;21/08/11 13:21:10&#39;,&#39;RRRR-MM-DD HH24:MI:SS&#39;) -- 조회하려는 시간의 시작시간
                AND MAXVALUE -- 현재 시간
WHERE ename = &#39;KING&#39;
ORDER BY versions_starttime NULLS FIRST; -- 시간이 지남에 따라 정렬/ NULL값을 제일 처음에</p>
<h2 id="flashback-transaction-query">FLASHBACK TRANSACTION QUERY</h2>
<p><img src="https://velog.velcdn.com/images/not-mini/post/7271d71a-1d90-4cba-8c90-f728091edae8/image.png" alt=""></p>
<p>예제 125번까지 보고 나서 20강 10분 정도에 다시 돌아와서 실습</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[실무에서 바로 쓰는 SQL 기본과 SQL 튜닝][ORACLE] 19강]]></title>
            <link>https://velog.io/@not-mini/%EC%8B%A4%EB%AC%B4%EC%97%90%EC%84%9C-%EB%B0%94%EB%A1%9C-%EC%93%B0%EB%8A%94-SQL-%EA%B8%B0%EB%B3%B8%EA%B3%BC-SQL-%ED%8A%9C%EB%8B%9DORACLE-19%EA%B0%95</link>
            <guid>https://velog.io/@not-mini/%EC%8B%A4%EB%AC%B4%EC%97%90%EC%84%9C-%EB%B0%94%EB%A1%9C-%EC%93%B0%EB%8A%94-SQL-%EA%B8%B0%EB%B3%B8%EA%B3%BC-SQL-%ED%8A%9C%EB%8B%9DORACLE-19%EA%B0%95</guid>
            <pubDate>Sat, 20 May 2023 01:15:30 GMT</pubDate>
            <description><![CDATA[<h2 id="flashback-query--실수로-삭제한-데이터-복구">FLASHBACK QUERY : 실수로 삭제한 데이터 복구</h2>
<p>실수로 DELETE FROM -- ; COMMIT; 을 실행하여 테이블 내 데이터가 모두 사라졌을 때 복구할 수 있는 기능</p>
<p>아무때나 복구할 수 있는 것은 아님</p>
<p>show parameter undo;</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/ab8e6144-e375-42ad-b670-355c106757a7/image.png" alt="결과"></p>
<p>undo_retention : 복구할 수 있는 최대 시간 (900초)</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/817b880d-b8a8-41f1-85ea-912af30e9690/image.png" alt="예제 99"></p>
<p>롤백은 마지막 커밋한 부분까지만 돌릴 수 있어서, ROLLBACK으로 살아나지 못함</p>
<p>SELECT *
FROM emp
AS OF TIMESTAMP(systimestamp - interval &#39;5&#39; minute); -- 현재 시간에서 5분전의 데이터를 조회</p>
<p>현재 시각을 출력하는 쿼리문</p>
<p>select systimestamp
from dual;</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/999cdd10-2a20-40ae-a328-eea88803992b/image.png" alt="현재 시각 출력"></p>
<p>INSERT INTO emp
SELECT *
FROM emp
AS OF TIMESTAMP(systimestamp - interval &#39;5&#39; minute); -- 현재 시간에서 5분전의 데이터를 다시 emp 테이블에 입력</p>
<p>commit;</p>
<p>사원 테이블의 월급 칼럼을 10분전 상태로 되돌리시오 - commit이후임</p>
<p>merge into emp e
using (select empno, sal
        from emp as of timestamp(systimestamp - interval &#39;10&#39; minute)
        ) s
on (e.empno = s.empno)
when matched then
update set e.sal = s.sal;</p>
<h2 id="flashback-table--실수로-삭제한-데이터-복구">FLASHBACK TABLE : 실수로 삭제한 데이터 복구</h2>
<p>show parameter undo; undo_retention 파라미터 값 이내로만 복구 가능</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/2b5263f0-54f0-4400-8a96-61265325c4f8/image.png" alt="예제 100"></p>
<ol>
<li>테이블을 복구(FLASHBACK)이 가능한 상태로 변경</li>
</ol>
<p>ALTER TABLE emp ENABLE ROW MOVEMENT;</p>
<ol start="2">
<li>FLASHBACK</li>
</ol>
<p>FLASHBACK TABLE emp TO TIMESTAMP(systimestamp - interval &#39;5&#39; minute);
-- 현재 시간에서 5분을 뺀 시간으로 emp 테이블을 복구함</p>
<ol start="3">
<li>commit</li>
</ol>
<p>commit;</p>
<h2 id="-flashback-drop--실수로-삭제한-데이터-복구">## FLASHBACK DROP : 실수로 삭제한 데이터 복구</h2>
<p>DROP(테이블 완전 삭제)에도 테이블 복구가 가능하다. (휴지통을 통해서)</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/58e7dfd1-79f5-4638-95a4-8208ef0a87ac/image.png" alt="예제 101"></p>
<p>SELECT *
FROM USER_RECYCLEBIN; //휴지통 조회</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/e9867e5c-e6aa-4617-9b65-4464c616c16e/image.png" alt="결과"></p>
<p>인덱스와 테이블이 DROP된 상태로 확인됨</p>
<p>FLASHBACK TABLE emp TO BEFORE DROP; -- 삭제된 테이블 복구/ 휴지통을 비우는 작업을 하지 않았다면 복구가능</p>
<p>PURGE RECYCLEBIN; -- 휴지통을 비우는 명령어</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[실무에서 바로 쓰는 SQL 기본과 SQL 튜닝][ORACLE] VIEW, INDEX, SEQUENCE]]></title>
            <link>https://velog.io/@not-mini/%EC%8B%A4%EB%AC%B4%EC%97%90%EC%84%9C-%EB%B0%94%EB%A1%9C-%EC%93%B0%EB%8A%94-SQL-%EA%B8%B0%EB%B3%B8%EA%B3%BC-SQL-%ED%8A%9C%EB%8B%9DORACLE-18%EA%B0%95</link>
            <guid>https://velog.io/@not-mini/%EC%8B%A4%EB%AC%B4%EC%97%90%EC%84%9C-%EB%B0%94%EB%A1%9C-%EC%93%B0%EB%8A%94-SQL-%EA%B8%B0%EB%B3%B8%EA%B3%BC-SQL-%ED%8A%9C%EB%8B%9DORACLE-18%EA%B0%95</guid>
            <pubDate>Sat, 20 May 2023 01:15:14 GMT</pubDate>
            <description><![CDATA[<h2 id="view">VIEW</h2>
<p>VIEW를 사용하는 이유 : 보안</p>
<p>VIEW
특정 테이블에 대해서 일부 데이터만 볼 수 있도록 해주는 것
다른 데이터를 못 보게 할 때 사용 (개인정보 보안)
실제 데이터를 가지고 있지 않고(복사의 형태가 아님), 테이블의 데이터를 바라보고 있음 (포인터와 비슷한 느낌..?)</p>
<p>CREATE VIEW 뷰이름
AS (서브쿼리절);</p>
<p>CREATE VIEW emp_view
AS
    (SELECT empno, ename, sal, job, deptno
    FROM emp
    WHERE job = &#39;SALESMAN&#39;);</p>
<p>SELECT * FROM emp_view;</p>
<p>VIEW에 대해서 데이터 수정을 할 경우, 원본 테이블의 값도 변경이 됨</p>
<h2 id="view-1">VIEW</h2>
<p>VIEW를 사용하는 이유 : 복잡한 쿼리문을 간단하게 검색하고자 할때</p>
<p>자주 실행되는 쿼리문의 결과를 view로 미리 생성해놓고, 해당 뷰의 전체를 출력하는 쿼리문을 실행
복잡한 쿼리문을 매번 작성하여 실행할 필요없이, 뷰만 조회하면 확인 가능함 - 쿼리문이 간결해짐</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/59ebc420-fc6c-4806-92f6-4aa4bcee6e03/image.png" alt="예제"></p>
<p>CREATE VIEW emp_view2
AS
    (SELECT deptno, round(avg(sal)) AS avgsal -- 칼럼 별칭을 반드시 지정해줘야 함
    FROM emp
    GROUP BY deptno);</p>
<p>select * from emp_view2;</p>
<h2 id="index--데이터-검색-속도를-높이기">INDEX : 데이터 검색 속도를 높이기</h2>
<p>CREATE INDEX 인덱스명
ON 테이블명(기준 칼럼명);</p>
<p>대용량 테이블에 대해서 쿼리를 빠르게 하기 위해 필요
책의 목차와 같은 느낌...?</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/97accb23-c8ce-40a0-9931-1e807b000367/image.png" alt="에제 97"></p>
<p>객체 : TABLE, VIEW, INDEX</p>
<p>인덱스가 없다면 정렬되지 않은 칼럼 값에 대해서 조건에 일치하는 행을 찾아야함(전체를 읽어야 함) - 검색 성능이 느려짐</p>
<p>인덱스
인덱스 기준 데이터와 그와 일치하는 테이블의 행의 위치를 찾을 수 있는 인덱스가 저장된 인덱스 테이블이 존재함
인덱스 테이블의 데이터는 정렬된 데이터로, 빠르게 해당 값을 찾을 수 있음.
인덱스 테이블 내의 해당 값을 찾아서 ROWID를 기준으로 테이블 내의 행의 위치를 찾아감</p>
<p>인덱스가 없을 시 FULL TABLE SCAN을 하게 되는 것에 비해 매우 빠른 검색 성능을 보임</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/d4ffa72f-13af-4b8e-add6-b113123bf50f/image.png" alt="인덱스 없이 쿼리문 실행시의 실행계획"></p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/171c6ca1-5849-4a82-a7d2-967e55041ac7/image.png" alt="인덱스 생성 후 실행계획"></p>
<p>CREATE INDEX emp_sal -- 인덱스명은 의미 있게 : &#39;테이블명_기준칼럼명&#39; 
ON emp(sal);</p>
<p>rowid란 칼럼은 원래 테이블에 존재함, 쿼리문 작성 시에 rowid 칼럼을 명시해줘야지 확인 가능
rowid : row의 물리적인 주소 (file 번호 + 블럭 번호 + row 번호)</p>
<p>rowid는 테이블, 인덱스에 존재함</p>
<p>월급에 걸린 인덱스를 확인하고 싶으면 아래와 같이 작성함</p>
<p>SELECT sal, rowid
FROM emp
WHERE sal &gt;= 0; -- 숫자의 경우 &quot;&gt;= 0&quot; / 문자의 경우 &quot;&gt; &#39; &#39;&quot;</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/096237be-b2be-447e-9c11-c3b359885874/image.png" alt="인덱스 출력 결과"></p>
<p>order by 절이 없음에도, sal칼럼이 오름차순으로 정렬되어있음</p>
<h2 id="sequence--절대로-중복되지-않는-번호-생성하기">SEQUENCE : 절대로 중복되지 않는 번호 생성하기</h2>
<p>CREATE SEQUENCE 시퀀스명; -- 옵션없이 생성
CREATE SEQUENCE seq1;</p>
<p>데이터를 입력할 시 특정 칼럼에 입력되는 순서대로의 번호를 입력하고 싶을 때 사용</p>
<p>SELECT seq1.nextval
FROM dual;</p>
<p>연속하여 실행할수록 1씩 증가한 값을 출력함</p>
<p>CREATE SEQUENCE 시퀀스명
INCREMENT BY 증감숫자
START WITH 시작문자
NOMINVALUE OR MINVALUE 최솟값
NOMAXVALUE OR MAXVALUE 최댓값
CYCLE OR NOCYCLE
CACHE OR NOCACHE -- 메모리에 시퀀스 값을 미리 할당</p>
<p>CREATE SEQUENCE seq2
START WITH    1
MAXVALUE 100
INCREMENT BY 1 -- 1부터 1씩 증가해서 최댓값 100까지
NOCYCLE; -- 100까지 나온 이후에 1로 다시 부여하지 않고, 끝내겠다는 의미</p>
<p>100을 넘어갈 시에 &#39;NEXTVALUE EXCEEDS MAXVALUE는 사례로 될 수 없습니다&#39;라는 오류 발생</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/ae749928-6186-4035-9c4e-8b0794747952/image.png" alt="사용 예시"></p>
<p>CREATE SEQUENCE dept_seq1
START WITH 50
INCREMENT BY 10; -- 50부터 시작하고 10씩 증가하는 시퀀스 생성</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[실무에서 바로 쓰는 SQL 기본과 SQL 튜닝][ORACLE] 17강]]></title>
            <link>https://velog.io/@not-mini/%EC%8B%A4%EB%AC%B4%EC%97%90%EC%84%9C-%EB%B0%94%EB%A1%9C-%EC%93%B0%EB%8A%94-SQL-%EA%B8%B0%EB%B3%B8%EA%B3%BC-SQL-%ED%8A%9C%EB%8B%9DORACLE-17%EA%B0%95</link>
            <guid>https://velog.io/@not-mini/%EC%8B%A4%EB%AC%B4%EC%97%90%EC%84%9C-%EB%B0%94%EB%A1%9C-%EC%93%B0%EB%8A%94-SQL-%EA%B8%B0%EB%B3%B8%EA%B3%BC-SQL-%ED%8A%9C%EB%8B%9DORACLE-17%EA%B0%95</guid>
            <pubDate>Sat, 20 May 2023 01:14:57 GMT</pubDate>
            <description><![CDATA[<h2 id="계층형-질의문으로-서열을-주고-데이터-출력하기">계층형 질의문으로 서열을 주고 데이터 출력하기</h2>
<p><img src="https://velog.velcdn.com/images/not-mini/post/dbe449d4-2110-43db-a3a1-6a4139ec23fd/image.png" alt="예제 89"></p>
<p>START WITH와 CONNECT BY PRIOR절을 작성하면 LEVEL이라는 칼럼을 출력할 수 있음</p>
<p>SELECT ename, level, sal, job
FROM emp
START WITH ename = &#39;KING&#39; -- KING을 서열 1위로 두고, 이후로 서열화
CONNECT BY PRIOR empno = mgr; -- 사원번호와 mgr이 연결됨</p>
<p>KING을 1위로 하여, MGR로 연결된 사원들을 서열화 함</p>
<p>SELECT RPAD(&#39; &#39;,level<em>3) || ename, sal, job -- RPAD(&#39; &#39;,level</em>3) : 서열만큼 공백이 채워져서 계층화되어 출력됨
FROM emp
START WITH ename = &#39;KING&#39; -- KING을 서열 1위로 두고, 이후로 서열화
CONNECT BY PRIOR empno = mgr; -- 사원번호와 mgr이 연결됨</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/d0828e3a-2d6d-4e45-8948-9b7b7e980e8f/image.png" alt="RPAD(&#39; &#39;,level*3) 예시"></p>
<p>서열이 2위인 사원들의 이름과 서열 직업 출력하시오</p>
<p>SELECT RPAD(&#39; &#39;,level<em>3) || ename, sal, job -- RPAD(&#39; &#39;,level</em>3)
FROM emp
WHERE level = 2
START WITH ename = &#39;KING&#39; -- KING을 서열 1위로 두고, 이후로 서열화
CONNECT BY PRIOR empno = mgr; -- 사원번호와 mgr이 연결됨</p>
<h2 id="계층형-질의문으로-서열을-주고-데이터-출력하기-1">계층형 질의문으로 서열을 주고 데이터 출력하기</h2>
<p><img src="https://velog.velcdn.com/images/not-mini/post/6106a6dd-3c6f-4941-b299-57a17a656ed6/image.png" alt=""></p>
<p>특정 행 포함 아래 서열들을 포함시키지 않고 출력하는 방법</p>
<p>SELECT RPAD(&#39; &#39;,level<em>3) || ename, sal, job -- RPAD(&#39; &#39;,level</em>3)
FROM emp
START WITH ename = &#39;KING&#39; 
CONNECT BY PRIOR empno = mgr
AND ename != &#39;BLAKE&#39;;</p>
<p>해당 조건을 WHERE절이 아니라 CONNECT BY절에 작성하여야 함
WHERE절에 작성하면 해당 행만 제외됨</p>
<p>SCOTT과 FORD를 포함한 그들의 팀원들이 제외하고 출력되도록 하시오</p>
<p>SELECT RPAD(&#39; &#39;,level<em>3) || ename, sal, job -- RPAD(&#39; &#39;,level</em>3)
FROM emp
START WITH ename = &#39;KING&#39; 
CONNECT BY PRIOR empno = mgr
AND ename NOT IN (&#39;SCOTT&#39;,&#39;FORD&#39;);</p>
<h2 id="계층형-질의문으로-서열을-주고-데이터-출력하기-2">계층형 질의문으로 서열을 주고 데이터 출력하기</h2>
<p>특정 조건대로 서열화하여 출력하기</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/b8ea3fbc-9411-4a84-9622-48100109ac3f/image.png" alt=""></p>
<p>SELECT RPAD(&#39; &#39;,level<em>3) || ename, sal, job -- RPAD(&#39; &#39;,level</em>3)
FROM emp
START WITH ename = &#39;KING&#39; 
CONNECT BY PRIOR empno = mgr
ORDER SIBLINGS BY sal desc; -- 서열 순서를 유지하면서 월급 높은 순대로 출력/같은 레벨상의 행들은 월급 높은 순으로 정렬되어 출력됨</p>
<p>SIBLINGS 옵션을 작성하지 않으면 아래와 같이 서열 순서가 깨져서 나옴</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/c31f1157-8809-43f9-ab64-b7221c1184ee/image.png" alt="출력 예시"></p>
<p>BLAKE를 포함한 팀원들만 출력하는데 서열을 유지한 상태로 월급이 낮은 사원부터 출력하시오</p>
<p>SELECT RPAD(&#39; &#39;,level<em>3) || ename, sal, job -- RPAD(&#39; &#39;,level</em>3)
FROM emp
WHERE level = 2
START WITH ename = &#39;BLAKE&#39; 
CONNECT BY PRIOR empno = mgr
ORDER SIBLINGS BY sal ASC; </p>
<p>SIBLINGS를 작성하지 않으면 단순히 서열 관계없이 월급이 낮은 순대로만 출력하게 됨</p>
<h2 id="계층형-질의문으로-서열을-주고-데이터-출력하기-3">계층형 질의문으로 서열을 주고 데이터 출력하기</h2>
<p><img src="https://velog.velcdn.com/images/not-mini/post/2f28d71b-7d65-4f80-9618-1ba248c93a67/image.png" alt=""></p>
<p>SYS_CONNECT_BY_PATH() : 서열 순서를 가로로 출력할 수 있음</p>
<p>SELECT ename, sys_connect_by_path(ename,&#39;/&#39;) as path
FROM emp
START WITH ename = &#39;KING&#39;
CONNECT BY PRIOR empno = mgr;</p>
<p>다음과 같이 월급도 같이 출력되게 하시오</p>
<p>SELECT ename || &#39;(&#39; || sal || &#39;)&#39;, sys_connect_by_path(ename || &#39;(&#39; || sal || &#39;)&#39; , &#39;/&#39;) as path
FROM emp
START WITH ename = &#39;KING&#39;
CONNECT BY PRIOR empno = mgr;</p>
<h1 id="ddl--테이블-생성-관리-삭제">DDL : 테이블 생성/ 관리/ 삭제</h1>
<h2 id="create-table--일반-테이블-생성">CREATE TABLE : 일반 테이블 생성</h2>
<p>CREATE TABLE 테이블명 (칼럼명 데이터타입,칼럼명 데이터타입,칼럼명 데이터타입,...);</p>
<p>예시)</p>
<p>CREATE TABLE emp3
(empno number(10), -- 숫자 10자리
 ename varchar1(10), -- 문자(영어) 10자리 (한글은 한 글자당 2바이트이므로 5글자)
 sal number(10,2), -- 총 10자리가 숫자인데, 그 중 2자리는 소수점
 hiredate date); -- 날짜</p>
<h2 id="create-temporary-table--임시-테이블-생성">CREATE TEMPORARY TABLE : 임시 테이블 생성</h2>
<p>CREATE GLOBAL TEMPORARY TABLE 테이블명 ( ............) ON COMMIT DELETE ROWS;</p>
<p>COMMIT시 데이터가 사라짐
세션 종료 후 재접속시 데이터는 사라지고, 테이블만 존재</p>
<p>어떤 작업을 위해서 임시로 데이터를 저장해야 할 때가 있음</p>
<p>영구 테이블로 임시 데이터를 저장하고 사용할 시, 후에 삭제하는 과정이 부담이 발생할 수 있음
-- 임시 데이터의 테이블을 지우려다가, 지우면 안되는 테이블을 지우게 될 수도 있음 (삭제 과정은 확인을 많이 필요로 하는 작업)</p>
<p>섣불리 필요없을 것 같은 테이블임에도 섣불리 지워내지 못해서, 데이터 낭비가 발생하게 되는 경우를 방지</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/9af6ce50-550b-429c-bbd9-850230586dee/image.png" alt="예제 94"></p>
<p>CREATE GLOBAL TEMPORARY TABLE emp3
( empno number(10)
  ename varchar2(10)
  sal number(10) )
ON COMMIT DELETE ROWS; -- COMMIT 실행시에 데이터가 삭제 됨 (테이블은 그대로고, 데이터만 사라짐)</p>
<p>임시테이블 옵션</p>
<ol>
<li>ON COMMIT DELETE ROWS : 커밋하면 데이터를 지워라</li>
<li>ON COMMIT PRESERVE ROWS : 세션을 종료하면 데이터를 지워라 (커밋하면 데이터가 저장됨)</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[실무에서 바로 쓰는 SQL 기본과 SQL 튜닝][ORACLE] 16강]]></title>
            <link>https://velog.io/@not-mini/%EC%8B%A4%EB%AC%B4%EC%97%90%EC%84%9C-%EB%B0%94%EB%A1%9C-%EC%93%B0%EB%8A%94-SQL-%EA%B8%B0%EB%B3%B8%EA%B3%BC-SQL-%ED%8A%9C%EB%8B%9DORACLE-16%EA%B0%95</link>
            <guid>https://velog.io/@not-mini/%EC%8B%A4%EB%AC%B4%EC%97%90%EC%84%9C-%EB%B0%94%EB%A1%9C-%EC%93%B0%EB%8A%94-SQL-%EA%B8%B0%EB%B3%B8%EA%B3%BC-SQL-%ED%8A%9C%EB%8B%9DORACLE-16%EA%B0%95</guid>
            <pubDate>Sat, 20 May 2023 01:14:29 GMT</pubDate>
            <description><![CDATA[<h2 id="select-for-update">SELECT FOR UPDATE</h2>
<p>SELECT절 마지막에 &#39;FOR UPDATE&#39; </p>
<p>SELECT를 실행하면서, 해당 행에 대해서 LOCK을 걸 수 있음
검색하는 동안에 그 누구도 갱신이 불가능함</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/2b50fb70-26da-4414-945a-d23127f92cc0/image.png" alt="예시"></p>
<p>SELECT문을 실행했음에도 COMMIT을 실행해야지, 접근이 가능함</p>
<p>SELECT ENAME, SAL, DEPTNO
FROM EMP
WHERE ENAME = &#39;JONES&#39;
FOR UPDATE;</p>
<h2 id="서브-쿼리를-사용하여-데이터-입력-insert">서브 쿼리를 사용하여 데이터 입력 (INSERT)</h2>
<p>INSERT문 아래에 입력하고자 하는 데이터를 가져오는 서브쿼리 입력
단일 행이 아닌 다중 행을 입력하고자 할때 사용</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/940227b7-5d3c-420f-a41d-896f758ff591/image.png" alt="예제 85"></p>
<p>CREATE TABLE EMP2
AS
 SELECT *
 FROM EMP;</p>
<p>테이블을 백업할 때 많이 사용되는 쿼리문</p>
<p>CREATE TABLE EMP3
AS
 SELECT *
 FROM EMP
 WHERE 1=2; -- FALSE</p>
<p>데이터 없이 테이블 구조만 복사함</p>
<p>INSERT INTO emp2(empno, ename, sal, deptno)
SELECT empno, ename, sal, deptno
FROM emp
WHERE deptno = 10;</p>
<p>부서 테이블과 같은 구조의 테이블을 DEPT2라는 이름으로 생성하고 부서번호가 20, 30번의 모든 컬럼의 데이터를 DEPT2에 입력</p>
<p>CREATE TABLE DEPT2
AS
  SELECT *
  FROM DEPT
  WHERE 1=2;</p>
<p>INSERT INTO DEPT2
SELECT *
FROM DEPT
WHERE DEPTNO IN (20,30);</p>
<h2 id="서브쿼리를-사용하여-데이터-수정-update">서브쿼리를 사용하여 데이터 수정 (UPDATE)</h2>
<p>SET절에 서브쿼리 작성</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/2ec71c1a-2556-4dfd-9075-5fecba3dbc90/image.png" alt="예제 86"></p>
<p>UPDATE emp
SET sal = (SELECT sal 
            FROM emp 
            WHERE ename = &#39;ALLEN&#39;)
WHERE job= &#39;SALESMAN&#39;;</p>
<p>부서번호가 30번인 사원들의 직업을 MARTIN의 직업으로 변경하세요</p>
<p>UPDATE emp
SET job = (SELECT job 
            FROM emp 
            WHERE ename = &#39;MARTIN&#39;)
WHERE DEPTNO = 30;</p>
<h2 id="서브쿼리를-사용하여-데이터-삭제-delete">서브쿼리를 사용하여 데이터 삭제 (DELETE)</h2>
<p><img src="https://velog.velcdn.com/images/not-mini/post/76c592e5-2163-4ff4-a756-9ca6591a35a2/image.png" alt="예제 87"></p>
<p>DELETE FROM emp
WHERE sal &gt; (SELECT sal 
            FROM emp 
            WHERE ename = &#39;SCOTT&#39;);</p>
<h2 id="서브쿼리를-사용하여-데이터-합치기-merge">서브쿼리를 사용하여 데이터 합치기 (MERGE)</h2>
<p><img src="https://velog.velcdn.com/images/not-mini/post/bb5f66c2-0fd5-4907-b8cc-5f46a2a60306/image.png" alt="예제 88"></p>
<p>ALTER TABLE dept
ADD sumsal number(10);</p>
<p>sum(sel)에 대한 쿼리문
SELECT deptno, sum(sal)
FROM emp
group by deptno;</p>
<p>MERGE INTO dept d
USING (SELECT deptno, sum(sal) as sumsal -- using 절에 작성함
        FROM emp
        GROUP BY deptno) v
ON (d.deptno = v.deptno)
WHEN MATCHED THEN
UPDATE SET d.sumsal = v.sumsal;</p>
<p>merge문 작성 시 alias는 매우 중요
into절의 테이블 값(혹은 서브쿼리)
using절의 테이블 값(혹은 서브쿼리)
alias 작성은 구분이 쉽게 되도록 작성</p>
<p>부서 테이블에 cnt라는 칼럼을 추가하고, 해당 부서 번호의 인원수로 값을 갱신하시오</p>
<p>alter table dept
add cnt number(10);</p>
<p>merge into dept d
USING (SELECT deptno, count(*) as cnt 
        FROM emp 
        GROUP BY DEPT) c
ON (d.deptno = c.deptno)
WHEN MATCHED THEN
UPDATE SET d.cnt = c.cnt;</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[실무에서 바로 쓰는 SQL 기본과 SQL 튜닝][ORACLE] 15강 DML]]></title>
            <link>https://velog.io/@not-mini/%EC%8B%A4%EB%AC%B4%EC%97%90%EC%84%9C-%EB%B0%94%EB%A1%9C-%EC%93%B0%EB%8A%94-SQL-%EA%B8%B0%EB%B3%B8%EA%B3%BC-SQL-%ED%8A%9C%EB%8B%9DORACLE-15%EA%B0%95-DML</link>
            <guid>https://velog.io/@not-mini/%EC%8B%A4%EB%AC%B4%EC%97%90%EC%84%9C-%EB%B0%94%EB%A1%9C-%EC%93%B0%EB%8A%94-SQL-%EA%B8%B0%EB%B3%B8%EA%B3%BC-SQL-%ED%8A%9C%EB%8B%9DORACLE-15%EA%B0%95-DML</guid>
            <pubDate>Sat, 20 May 2023 01:14:09 GMT</pubDate>
            <description><![CDATA[<h2 id="merge--데이터-입력-수정-삭제를-동시에">MERGE : 데이터 입력, 수정, 삭제를 동시에</h2>
<p><img src="https://velog.velcdn.com/images/not-mini/post/37f948d9-710e-41ef-9c89-bcaa2b893e80/image.png" alt="예제 82"></p>
<p>예시)</p>
<p>alter table emp
add loc varchar2(10);</p>
<p>merge into emp e
using dept d
on (e.deptno = d.deptno)
when matched then         -- 일치하면
update set e.loc = d.loc  -- 칼럼 업데이트
when not matched then     -- 일치하지 않으면
insert (e.empno, e.deptno, e.loc) values (1111, d.deptno, d.loc) -- 행 삽입</p>
<p>사원 테이블에 부서명 칼럼을 추가하고 해당 사원의 부서명으로 값을 갱신하시오</p>
<p>alter table emp
add dname varchar2(10)</p>
<p>merge into emp e
using dept d
on (e.deptno = d.deptno
when matched then
update set e.dname = d.dname;</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/89cec7b1-5e1a-4919-829b-33e37af9f827/image.png" alt="실행 결과"></p>
<h2 id="lock">LOCK</h2>
<p>데이터의 일관성을 보장하기 위해서 다른 세션이 어느 하나의 행에 DML문을 실행하고 COMMIT을 하기 전까지, 다른 세션에서 동일한 행을 갱신할 수 없도록 막는 기능</p>
<p>DML문을 실행 후 COMMIT을 하지 않으면, 다른 세션의 데이터와 달라지게 됨
여기서 오는 일관성에 관한 문제를 방지하기 위해, 아예 해당 데이터(테이블 또는 행)에 대한 접근을 막음</p>
<p>DML을 수행한 해당 세션에서 COMMIT을 실행하면, LOCK 상태가 해제됨</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/8f0fd99c-69d8-4fee-8cc5-d0f9e680cae2/image.png" alt="예시"></p>
<p>세션 1 UPDATE문의 실행결과가 COMMIT으로 영구저장 될때까지, 세션 2는 접근이 불가능함 (LOCK 상태) </p>
<p>세션1이 COMMIT을 수행한 후, 바로 LOCK이 해제되며, UPDATE문이 실행됨</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/dbbf3b82-4925-4217-bf15-d3ff15325578/image.png" alt="최종적으로 COMMIT을 실행한 세션의 데이터를 보게 됨"></p>
<p>오른쪽 세션에서 아직 COMMIT을 실행하지 않았기에 9000을 출력함</p>
<blockquote>
<p>어느 세션이든 최종적으로 COMMIT한 데이터를 보게 됨</p>
</blockquote>
<p>세션에서 데이터를 갱신하고 있으면, 다른 세션에선 절대 갱신이 불가능하도록 하는 것</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/4b5dce5e-dc71-41d9-a2fa-2cbe57bdfd0a/image.png" alt="예제"></p>
<p>ALLEN의 전체 행에 대해서 LOCK을 걸기 때문에, 실행이 불가능하다</p>
<blockquote>
<p>UPDATE하는 필드에만 LOCK을 거는 것이 아니라, 전체 행에 대해서 LOCK을 건다</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[실무에서 바로 쓰는 SQL 기본과 SQL 튜닝][ORACLE] 14강 DML]]></title>
            <link>https://velog.io/@not-mini/%EC%8B%A4%EB%AC%B4%EC%97%90%EC%84%9C-%EB%B0%94%EB%A1%9C-%EC%93%B0%EB%8A%94-SQL-%EA%B8%B0%EB%B3%B8%EA%B3%BC-SQL-%ED%8A%9C%EB%8B%9DORACLE-14%EA%B0%95-DML</link>
            <guid>https://velog.io/@not-mini/%EC%8B%A4%EB%AC%B4%EC%97%90%EC%84%9C-%EB%B0%94%EB%A1%9C-%EC%93%B0%EB%8A%94-SQL-%EA%B8%B0%EB%B3%B8%EA%B3%BC-SQL-%ED%8A%9C%EB%8B%9DORACLE-14%EA%B0%95-DML</guid>
            <pubDate>Sat, 20 May 2023 01:13:50 GMT</pubDate>
            <description><![CDATA[<h2 id="sql-종류">SQL 종류</h2>
<ol>
<li>QUERY문 :</li>
</ol>
<p>SELECT 
FROM
WHERE 
GROUP BY
HAVING
ORDER BY</p>
<ol start="2">
<li>DML문 (Data Manipulation Language) : insert, update, delete, merge</li>
<li>DDL문</li>
<li>DCL문</li>
<li>TCL문</li>
</ol>
<h2 id="insert">INSERT</h2>
<p>INSERT INTO 테이블명(컬럼명1,컬럼명2,컬럼명3 ...)
VALUES (값1, 값2, 값3, ....)</p>
<p>문자 값 : 싱글 쿼테이션 마크
날짜 값 : to_date() 함수</p>
<p>예시)
INSERT INTO emp(empno, ename, sal, job, hiredate)
VALUES (2812, &#39;JACK&#39;, 3500, &#39;ANALYST&#39;, to_date(&#39;2019/06/05&#39;, &#39;RRRR/MM/DD&#39;));</p>
<p>INSERT INTO 테이블명
VALUES (값1, 값2, 값3, ....)</p>
<p>위와 같이 작성시, 모든 칼럼에 대한 값을 작성하여야 함</p>
<h2 id="commit영구-저장-rollback취소">COMMIT(영구 저장)/ ROLLBACK(취소)</h2>
<p>ROLLBACK : INSERT, UPDATE, DELETE 실행 결과를 취소
COMMIT : INSERT, UPDATE, DELETE 실행 결과를 영구히 저장</p>
<h2 id="update">UPDATE</h2>
<p>UPDATE 테이블명
SET 칼럼명 = 값 -- 세팅값 지정
WHERE 조건; -- 어떤 행을 바꿀건지</p>
<p>예시)
UPDATE emp
SET sal = 3200
WHERE ename = &#39;SCOTT&#39;;</p>
<h2 id="deletetruncatedrop--데이터-삭제">DELETE/TRUNCATE/DROP : 데이터 삭제</h2>
<p>DELETE FROM 테이블명
WHERE 조건;</p>
<p>WHERE절을 작성하지 않으면 테이블 전체를 지우게 된다. - ROLLBACK 가능함</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/7c4a21c0-a8ce-4f81-895c-100c6a730307/image.png" alt="삭제 명령어"></p>
<p>TRUNCATE TABLE 테이블명; -- ROLLBACK 불가능함 (COMMIT을 포함한 명령)</p>
<p>DROP TABLE 테이블명; -- 휴지통 기능이 있어 다시 복구 할 수 있음</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[실무에서 바로 쓰는 SQL 기본과 SQL 튜닝][ORACLE] 13강]]></title>
            <link>https://velog.io/@not-mini/%EC%8B%A4%EB%AC%B4%EC%97%90%EC%84%9C-%EB%B0%94%EB%A1%9C-%EC%93%B0%EB%8A%94-SQL-%EA%B8%B0%EB%B3%B8%EA%B3%BC-SQL-%ED%8A%9C%EB%8B%9DORACLE-13%EA%B0%95</link>
            <guid>https://velog.io/@not-mini/%EC%8B%A4%EB%AC%B4%EC%97%90%EC%84%9C-%EB%B0%94%EB%A1%9C-%EC%93%B0%EB%8A%94-SQL-%EA%B8%B0%EB%B3%B8%EA%B3%BC-SQL-%ED%8A%9C%EB%8B%9DORACLE-13%EA%B0%95</guid>
            <pubDate>Sat, 20 May 2023 01:13:29 GMT</pubDate>
            <description><![CDATA[<h2 id="not-in">NOT IN</h2>
<p>관리자인 사원들의 이름을 출력하시오</p>
<pre><code>  SELECT ENAME,SAL,JOB
  FROM EMP
  WHERE EMPNO IN (SELECT MGR
                  FROM EMP);</code></pre><p>예제) 관리자가 아닌 사원들의 이름을 출력하시오</p>
<pre><code>  SELECT ENAME
  FROM EMP
  WHERE EMPNO NOT IN (SELECT MGR
                  FROM EMP);</code></pre><p>위 쿼리에서 결과가 안 나온다.. MGR 칼럼에 NULL값이 포함되어 있기 때문</p>
<p>NOT IN = &#39;!=ALL&#39;</p>
<p>TRUE AND TREU AND ... AND NULL = NULL</p>
<p>칼럼 값 중에 NULL이 있으면 전체 결과 값이 NULL이 되버림 (NULL은 TRUE/FALSE도 아닌 알 수 없는 값)</p>
<p>따라서 아래와 같이 서브쿼리의 결과 값에서 NULL값이 포함되지 않도록 WHERE절을 작성하여야 함</p>
<pre><code>  SELECT ENAME
  FROM EMP
  WHERE EMPNO NOT IN (SELECT MGR
                  FROM EMP
                  WHERE MGR IS NOT NULL);</code></pre><pre><code>  SELECT ENAME
  FROM EMP
  WHERE EMPNO NOT IN (SELECT NVL(MGR,-1)
                  FROM EMP);</code></pre><p>서브 쿼리에서 NOT IN을 쓸 때에는 NULL값이 반환값으로 들어가지 않도록 해야 함</p>
<h2 id="exists-not-exist">EXISTS/ NOT EXIST</h2>
<p>보통은 서브쿼리부터 실행되는데, EXIST문을 작성하면 메인쿼리부터 실행됨</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/a3937f2d-b26b-465c-bcb6-d1a47175febc/image.png" alt="예제 74"></p>
<pre><code>  SELECT *
  FROM DEPT D
  WHERE EXISTS (SELECT *
                  FROM EMP E
                  WHERE E.DEPTNO = D.DEPTNO);</code></pre><p>먼저 메인쿼리를 실행하여, DEPTNO의 전체 테이블 정보를 가져온 후, 서브 쿼리의 DEPT.DEPTNO 조건문에 값을 대입하면서 실행된다.</p>
<p>존재하지 않는 컬럼만 출력하려면, NOT EXIST</p>
<pre><code>  SELECT *
  FROM DEPT D
  WHERE NOT EXISTS (SELECT *
                  FROM EMP E
                  WHERE E.DEPTNO = D.DEPTNO);</code></pre><h2 id="having절의-서브-쿼리">HAVING절의 서브 쿼리</h2>
<p><img src="https://velog.velcdn.com/images/not-mini/post/9f56db85-e395-4d15-83fe-16e11868f2bb/image.png" alt="예제 75"></p>
<pre><code>  SELECT JOB, SUM(SAL)
  FROM EMP
  GROUP BY JOB
  HAVING SUM(SAL) &gt; (SELECT SUM(SAL)  -- 그룹함수에 대한 조건은 HAVING절에 작성
                      FROM EMP
                      WHERE JOB=&#39;SALESMAN&#39;);</code></pre><p>예제) 부서번호, 부서번호별 인원수를 출력하는데 10번 부서번호의 인원수보다 더 큰 것만 출력하시오</p>
<pre><code>  SELECT DEPTNO, COUNT(*) 
  FROM EMP 
  GROUP BY DEPTNO
  HAVING COUNT(*) &gt; (SELECT COUNT(*)
                      FROM EMP
                      WHERE DEPTNO = 10);</code></pre><h2 id="from절의-서브쿼리">FROM절의 서브쿼리</h2>
<p><img src="https://velog.velcdn.com/images/not-mini/post/fa6018e3-e512-4f1e-9eba-c69c3001fe17/image.png" alt="예제 76"></p>
<p>분석함수는 WHERE절에는 작성 불가능</p>
<pre><code>  SELECT *
  FROM (SELECT ENAME, SAL, RANK() OVER (ORDER BY SAL DESC) RNK
          FROM EMP
        );</code></pre><p>위와 같이 실행하면 FROM절 안의 서브쿼리가 가장 먼저 실행됨 - 서브쿼리의 결과를 메모리에 올려놓음</p>
<p>실행 순서 : (서브쿼리 내부) FROM -&gt; (서브쿼리 내부) SELECT -&gt; (메인쿼리) FROM -&gt; (메인쿼리) WHERE -&gt; (메인쿼리) SELECT</p>
<pre><code>  SELECT *
  FROM (SELECT ENAME, SAL, RANK() OVER (ORDER BY SAL DESC) RNK
          FROM EMP
        )
  WHERE RNK = 1;</code></pre><p>예제) 직업이 SALESMAN인 사원들 중에서 가장 먼저 입사한 사원들의 이름과 입사일을 출력하시오</p>
<pre><code>  SELECT *
  FROM (SELECT ENAME, HIREDATE, RANK() OVER (ORDER BY HIREDATE DESC) RANK
       FROM EMP
       WHERE JOB = &#39;SALESMAN&#39;)
  WHERE RANK = 1;</code></pre><h2 id="select-절의-서브-쿼리">SELECT 절의 서브 쿼리</h2>
<p>그룹함수의 결과를 일반 칼럼과 같이 출력하고 싶을 때 사용</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/50bd023f-304b-4060-adc6-7df9191d454c/image.png" alt="예제 77"></p>
<pre><code>  SELECT ENAME, SAL (SELECT MAX(SAL) FROM EMP WHERE JOB=&#39;SALESMAN&#39;) AS MAX1,
                      (SELECT MIN(SAL) FROM EMP WHERE JOB=&#39;SALESMAN&#39;) AS MIN1
  FROM EMP
  WHERE JOB=&#39;SALESMAN&#39;;</code></pre><p>SELECT 문의 6가지 절 (서브쿼리 사용 유무)</p>
<p>SELECT         (O)
FROM           (O)
WHERE        (O)
GROUP BY    (X)
HAVING        (O)
ORDER BY    (O)</p>
<p>예제) 부서번호가 20번인 사원들의 이름과 월급을 출력하고, 그 옆에 20번 부서번호인 사원들의 평균 월급이 출력되게 하시오</p>
<pre><code>  SELECT ENAME, SAL ,(SELECT AVG(SAL) FROM EMP WHERE DEPTNO = 20) 평균
  FROM EMP
  WHERE DEPTNO = 20;</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[실무에서 바로 쓰는 SQL 기본과 SQL 튜닝][ORACLE] 12강 ]]></title>
            <link>https://velog.io/@not-mini/%EC%8B%A4%EB%AC%B4%EC%97%90%EC%84%9C-%EB%B0%94%EB%A1%9C-%EC%93%B0%EB%8A%94-SQL-%EA%B8%B0%EB%B3%B8%EA%B3%BC-SQL-%ED%8A%9C%EB%8B%9DORACLE-12%EA%B0%95</link>
            <guid>https://velog.io/@not-mini/%EC%8B%A4%EB%AC%B4%EC%97%90%EC%84%9C-%EB%B0%94%EB%A1%9C-%EC%93%B0%EB%8A%94-SQL-%EA%B8%B0%EB%B3%B8%EA%B3%BC-SQL-%ED%8A%9C%EB%8B%9DORACLE-12%EA%B0%95</guid>
            <pubDate>Sat, 20 May 2023 01:13:04 GMT</pubDate>
            <description><![CDATA[<h1 id="집합-연산자---데이터를-위아래로-연결">집합 연산자 - 데이터를 위아래로 연결</h1>
<p>JOIN은 데이터를 양옆으로 연결</p>
<h2 id="union-all">UNION ALL</h2>
<p><img src="https://velog.velcdn.com/images/not-mini/post/a86a60c1-992f-439f-86b1-06cc11455cd7/image.png" alt="예제 67"></p>
<p>SELECT DEPTNO, SUL(SAL)
FROM EMP
GROUP BY DEPTNO;</p>
<p>SELECT SUM(EMP)
FROM EMP;</p>
<p>위 두 쿼리문의 결과를 위아래로 연결</p>
<p>SELECT DEPTNO, SUL(SAL)
FROM EMP
GROUP BY DEPTNO
UNION ALL
SELECT SUM(EMP)
FROM EMP;</p>
<p>위와 같이 실행하면 질의 블록은 부정확한 수의 결과 열을 가지고 있습니다라는 오류 발생
두 개의 쿼리에서 컬럼의 개수가 동일해야함</p>
<p>SELECT DEPTNO, SUL(SAL)
FROM EMP
GROUP BY DEPTNO
UNION ALL
SELECT NULL,SUM(EMP) -- 컬럼을 추가할 게 없으니 NULL로 작성
FROM EMP;</p>
<p>위 아래 두 개의 쿼리문에서, 컬럼의 개수와 데이터 타입이 동일하여야 함.</p>
<p>null/ deptno는 일치하지 않아도 출력이 되지만, to_number(null)로 수행하는 것이 성능이 더 좋음</p>
<p>SELECT DEPTNO, SUL(SAL)
FROM EMP
GROUP BY DEPTNO
UNION ALL
SELECT to_number(NULL),SUM(EMP) -- number 형식으로 바꿈
FROM EMP;</p>
<p>컬럼명도 되도록이면 동일하게 작성 - order by절에서 정렬시 사용</p>
<p>SELECT DEPTNO, SUL(SAL)
FROM EMP
GROUP BY DEPTNO
UNION ALL
SELECT to_number(NULL) as deptno,SUM(EMP) -- 컬럼명 동일 (deptno)
FROM EMP
order by deptno asc; -- order by절은 맨 아래에만 작성 가능</p>
<p>예제) 직업과 직업별 토탈월급을 출력하는데 맨 아래에 전체 토탈 월급도 출력하세요</p>
<pre><code>  select job, sum(sal)
  from emp
  group by job
  union all
  select to_char(null) as job, sum(sal) -- 컬럼 개수, 타입, 컬럼명 일치
  from emp
  order by job asc;</code></pre><h2 id="union">UNION</h2>
<p>?????????????????????????????????????????????????????????????????????????
UNION : 데이터를 정렬하여 출력
UNION ALL : 데이터를 정렬하지 않고, 단순히 붙여서 출력</p>
<h2 id="intersect--데이터-교집합-출력">INTERSECT : 데이터 교집합 출력</h2>
<p>두 쿼리문에 대해서 중복되는 결과만 출력하며, 제일 첫번째 칼럼을 기준으로 정렬하여 출력함</p>
<pre><code>SELECT ENAME, SAL, JOB, DEPTNO
    FROM EMP
    WHERE DEPTNO IN (10,20)
INTERSECT
SELECT ENAME, SAL, JOB, DEPTNO
    FROM EMP
    WHERE DEPTNO IN (20,30);</code></pre><p><img src="https://velog.velcdn.com/images/not-mini/post/e663e4a7-8467-44c6-9e39-4b45d53d8066/image.png" alt="출력 결과"></p>
<p>사원 테이블과 부서 테이블과의 공통된 부서번호가 무엇인지 출력하시오</p>
<p>select deptno
from emp
intersect
select deptno
from dept;</p>
<h2 id="minus--데이터-차집합-출력">MINUS : 데이터 차집합 출력</h2>
<p>위 쿼리문에서 아래 쿼리문의 결과를 뺀 결과를 출력함</p>
<pre><code>SELECT ENAME, SAL, JOB, DEPTNO
    FROM EMP
    WHERE DEPTNO IN (10,20)
MINUS
SELECT ENAME, SAL, JOB, DEPTNO
    FROM EMP
    WHERE DEPTNO IN (20,30);</code></pre><p>DEPTNO = 10인 행만 출력</p>
<pre><code>SELECT ENAME, SAL, JOB, DEPTNO
    FROM EMP
    WHERE DEPTNO IN (20,30)
MINUS
SELECT ENAME, SAL, JOB, DEPTNO
    FROM EMP
    WHERE DEPTNO IN (10,20);</code></pre><p>DEPTNO = 30인 행만 출력</p>
<p>따라서, 위 두개의 쿼리 실행 결과는 다름</p>
<p>부서테이블에는 존재 하는데 사원테이블에는 존재하지 않는 부서번호는?</p>
<p>SELECT DEPTNO
FROM DEPT
MINUS
SELECT DEPTNO
FROM EMP;</p>
<h2 id="단일행-서브쿼리-중요">단일행 서브쿼리 (중요..)</h2>
<p>서브 쿼리에서 메인쿼리로 하나의 값이 리턴되는 경우
연산자 : =,!=,^=,&lt;&gt;,&gt;,&lt;,&gt;=,&lt;=</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/01294573-c6d1-4c8d-974a-5e753de94510/image.png" alt="예제 71"></p>
<pre><code>  SELECT ENAME, SAL -- 메인쿼리
  FROM EMP
  WHERE SAL &gt; (SELECT SAL  -- 서브쿼리
              FROM EMP
              WHERE ENAME = &#39;JONE&#39;);</code></pre><p>ALLEN 보다 더 늦게 입사한 사원들의 이름과 월급을 출력하시오</p>
<pre><code>  SELECT ENAME, SAL
  FROM EMP
  WHERE HIREDATE &gt; (SELECT HIREDATE
                      FROM EMP
                      WHERE ENAME = &#39;ALLEN&#39;);</code></pre><h2 id="다중-행-서브쿼리">다중 행 서브쿼리</h2>
<p>서브 쿼리에서 메인쿼리로 여러개의 값이 리턴되는 경우
연산자 : IN, NOT IN, &gt;ALL, &lt;ALL, &gt;ANY, &lt;ANY ,</p>
<p><img src="https://velog.velcdn.com/images/not-mini/post/184ff481-ecc1-4789-87c4-29851f8f40d4/image.png" alt="예제 72"></p>
<pre><code>  SELECT ENAME, SAL
  FROM EMP
  WHERE SAL IN (SELECT SAL
              FROM EMP
              WHERE JOB = &#39;SALESMAN&#39;);</code></pre><p>서브쿼리에서 다중 행을 반환하므로, IN 연산자 사용</p>
<p>다중 행 서브쿼리 : IN
단일 행 서브쿼리 : =</p>
<p>부서번호가 20번인 사원들과 같은 직업을 갖는 사원들의 이름과 직업을 출력</p>
<pre><code>  SELECT ENAME, JOB
  FROM EMP
  WHERE JOB IN (SELECT JOB
              FROM EMP
              WHERE DEPTNO = 20);</code></pre>]]></description>
        </item>
    </channel>
</rss>