반응형

문제출처

https://programmers.co.kr/learn/courses/30/lessons/59045

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

문제풀이

보호소에 들어올 당시에는 중성화되지 않았지만, 보호소를 나갈때 중성화된 동물'을 찾는 문제이다.

키 값으로 INNER JOIN을 한뒤 ANIMAL_INS에서는 Intact로 시작하고, ANIMAL_OUTS에서는 Spayed나 Neutered로 시작하는 데이터를 찾으면 된다.

 

소스코드

 

SELECT A.ANIMAL_ID
      ,A.ANIMAL_TYPE
      ,A.NAME
FROM   ANIMAL_INS A
      ,ANIMAL_OUTS B
WHERE  A.ANIMAL_ID   = B.ANIMAL_ID
AND    A.ANIMAL_TYPE = B.ANIMAL_TYPE
AND    A.SEX_UPON_INTAKE LIKE 'Intact%'
AND    (B.SEX_UPON_OUTCOME LIKE 'Neutered%' OR B.SEX_UPON_OUTCOME LIKE 'Spayed%')
반응형

'Database' 카테고리의 다른 글

[SQL 튜닝] 2. 옵티마이저(Optimizer)  (0) 2019.04.22
[SQL 튜닝] 1. 실행계획(Execution plan)  (2) 2019.04.22
오라클 다중 WHERE조건  (0) 2018.06.25
무결성 (Integrity)  (0) 2018.01.12
JOIN (조인)  (0) 2018.01.12
반응형

  1. 옵티마이저의 개념
사용자가 실행한 SQL을 해석하고 데이터를 추출하기 위한 실행계획을 수립하는 프로세스
오라클은 RBO(Rule Based Optimizer)와 CBO(Cost Based Optimizer)를 제공하고 나머지 DBMS는 CBO만을 제공함
  1. 옵티마이저의 종류
1) RBO
기본적으로 15개의 순위가 매겨진 규칙이 존재(이를 기초로 해서 실행계획을 수립)
SQL에 대한 실행계획이 하나 이상일 경우 순위가 높은 규칙을 이용한다.
수립될 실행계획이 예측 가능하기 때문에 개발자가 원하는 처리 경로로 유도하기가 쉽다.

2) CBO
 대상 row들을 처리하는데 필요한 자원 사용을 최소화해서, 궁극적으로 데이터를 빨리 처리하는데 목적이 있음.
CBO는 통계정보를 기반으로 비용을 산정하는데 CBO의 성능을 최적의 상태로 유지시키기 위해서 테이블, 인덱스, 클러스터 등을 대상으로통계정보를 생성하는것이 중요하다(ANALYZE 작업)

             ANALYZE 의 예
            

            ANALYZE 실행 여부 확인
            

  1. RBO와 CBO의 실행계획 비교
            

            CBO에서의 실행계획
            

            RBO에서의 실행계획
            

실행계획을 보면 CBO와 RBO가 조인 순서가 다름을 알 수 있다. 이를 트리형태로 나타내보면 다음과 같다.

            

 CBO를 보면 2번의 테이블(DEPT)을 먼저 읽고 4번이 조인형태로 연결이 된다. 하지만 RBO를 보면 3번 테이블(EMP)을 먼저 읽는다. 즉 where절에 있던 테이블을 기준으로 먼저 읽었다.
            
        



반응형

'Database' 카테고리의 다른 글

[프로그래머스 59045] 보호소에서 중성화한 동물  (0) 2020.04.29
[SQL 튜닝] 1. 실행계획(Execution plan)  (2) 2019.04.22
오라클 다중 WHERE조건  (0) 2018.06.25
무결성 (Integrity)  (0) 2018.01.12
JOIN (조인)  (0) 2018.01.12
반응형

1. 실행계획

실행계획이란?

사용자가 SQL을 실행하여 데이터를 추출하려고 할 때 옵티마이저가 수립하는 작업절차를 뜻한다.

이런 실행계획을 수립하는 옵티마이저의 실행 단계는 3단계로 분리할 수 있다.

1) SQL 해석

2) 실행계획 수립

3) 실행

1. 오라클 DBMS를 통해 실행계획 확인하는 방법

오라클 DBMS에서 제공하는 두가지 명령어  

1) explain plan

2) set autotrace

Explain plan 방법

1
2
3
4
5
6
7
8
-- EXPLAIN PLAN
예제) EXPLAIN PLAN
      SET STATEMENT_ID = 'TEST1' INTO PLAN_TABLE
      FOR
      SELECT /*+USE_NL(e d)*/
              e.name, e.deptno, d.dname
      FROM emp e, dept d
      WHERE e.deptno = d.deptno;
cs

SQL에 대한 생행계획만을 확인할 뿐 데이터를 처리를 하지 않음

때문에 데이터베이스에 어떠한 부하도 주지 않는다.

튜닝하고자 하는 SQL이 다수일 경우 매번 명령을 수행시켜야하는 불편함이 존재한다.

데이터를 처리하지 않기 때문에 I/O관련 시간도 측정할 수 없다.(SORTING 포함)

PLAN_TABLE에 저장된 결과를 확인하기 위해 다음과 같은 SELECT명령어를 실행시켜야한다.

1
2
3
SELECT *
FROM TABLE(DBMS_XPLAN.DISPLAY
            ('PLAN_TABLE''TEST1''ALL'));
cs

Set autotrace 방법

EXPLAIN 명력과 달리 한번의 명령으로 여러개의 SQL에 대한 실행계획을 볼 수 있다.

또한, 다양하게 옵션을 사용할 수 있어서 여러가지의 정보를 선택적으로 확인할 수 있다.

1
2
3
4
5
SET AUTOTRACE ON
SELECT /*+USE_NL(e d)*/
          e.name, e.deptno, d.dname
FROM emp e, dept d
WHERE e.deptno = d.deptno;
cs

여기서 set autotrace on 이부분에 옵션을 추가하는데 몇가지 예를 알아보도록 하자

-- SET AUTOTRACE 의 몇가지 옵션 예

SET AUTOTRACE ON EXPLAIN;

출력결과와 실행계획까지만 나타냄 통계정보는 생략

SET AUTOTRACE ON STATISTICS;

출력결과와 실행계획을 생략하고 I/O관련 정보를 선택적으로 보여줌

SET AUTOTRACE ON TRACEONLY;

데이터가 상당히 클때 사용하는데 출력결과를 나타내지 않음

SET AUTOTRACE ON TRACEONLY EXPLAIN;

데이터를 처리하지 않고 실행계획만을 보여줌(많이 사용함)

SET AUTOTRACE ON TRACEONLY STATISTICS;

데이터를 처리하지 않고 I/O관련 정보를 보여줌

SET AUTOTRACE ON OFF;

사용하지 않을때 사용

지금까지 옵티마이저의 실행계획을 확인하는 방법을 알아보았다. 이런 실행계획은 분석하여 SQL의 성능을 향상시키는데 목적을 둔다. 때문에 실행계획을 확인하는 것보다 분석하여 어떻게 개선할 것이지를 정하는 것이 더욱 중요하다.

2. 실행계획 분석

1
2
3
4
5
SET AUTOTRACE ON TRACEONLY EXPLAIN;
SELECT /*+USE_NL(e d)*/
          e.name, e.deptno, d.dname
FROM emp e, dept d
WHERE e.deptno = d.deptno;
cs

이 쿼리의 실행계획을 보면 다음과 같다.

들여쓰기를 기준으로 구분할 수 있는데 1번 작업과 연관되는 작업이 2번과 5번임을 알 수 있다. 같은 들여쓰기라면 위에 있는 명령이 선실행되므로 2번이 실행되고 5번이 실행된다.

즉, 같은 들여쓰기 DEPTH를 가지고 있다면 위에 있는 작업이 먼저 실행되는 작업이고 아래에 있는 것이 나중에 실행되는 것이다.

또 2번과 연관된 작업이 3번과 4번이기 때문에 이 실행계뢱을 보아 트리구조로 나타내면 다음과 같다.

이때 가장먼저 실행되는 작업은 가장 왼쪽에서 아래에 있는 노드이다.

3 -> 4 -> 2 -> 5 -> 1 -> 0 순으로 실행된다.

실행계획을 어떻게 확인하고 분석하는지 알아보았다. 다음장에서는 옵티마이저에 대해 알아보도록 한다.

반응형

'Database' 카테고리의 다른 글

[프로그래머스 59045] 보호소에서 중성화한 동물  (0) 2020.04.29
[SQL 튜닝] 2. 옵티마이저(Optimizer)  (0) 2019.04.22
오라클 다중 WHERE조건  (0) 2018.06.25
무결성 (Integrity)  (0) 2018.01.12
JOIN (조인)  (0) 2018.01.12
반응형

TABLE = BOOK

BOOK_NO 

NAME 

EDITION 

 100

JAVA 

 100

JAVA 

 101

C++ 


이와 같은 데이터가 있다고 가정할 경우 책번호와 책이름을 조회하되 같은 책이 있을 경우 EDITION이 높은 것을 조회하고자 한다.


많은 방법이 있겠지만 한가지 방법을 소개한다.


SELECT BOOK_NO, NAME, EDITION

FROM BOOK

WHERE 1=1

AND (BOOK_NO, NAME, EDITION) IN (SELECT BOOK_NO, NAME, MAX(EDITION) AS EDITION FROM BOOK GROUP BY BOOK_NO, NAME)


이와 같은 방법으로 WHERE 조건에 괄호와 IN 그리고 서브쿼리를 사용하여 조건을 부여할 수 있다.

반응형

'Database' 카테고리의 다른 글

[SQL 튜닝] 2. 옵티마이저(Optimizer)  (0) 2019.04.22
[SQL 튜닝] 1. 실행계획(Execution plan)  (2) 2019.04.22
무결성 (Integrity)  (0) 2018.01.12
JOIN (조인)  (0) 2018.01.12
오라클 SQL Developer 2018.01.09  (0) 2018.01.09
반응형

1. 무결성에는 개체 무결성(Entity Integrity)

              참조 무결성(Relational Integrity)

              도메인 무결성(Domain Integrity) 이 있다.


2. 개체 무결성

   개체 무결성은 릴레이션에서 저장되는 튜플(tuple)의

   유일성을 보장하기 위한 제약조건이다.

   

3. 참조 무결성

   참조 무결성은 릴레이션 간의 데이터 일관성을

   보장하기 위한 제약조건이다.

   

4. 도메인 무결성

   도메인 무결성은 허용 가능한 값의 범위를

   지정하기 위한 제약조건이다.

  

5. 제약조건의 종류


   1) Primary key(pk:p)

      해당 컬럼의 값은 반드시 존재해야 하며, 유일해야 한다.

      (not null 과 unique 가 결합된 형태)

    

   2) Foreign key(fk:f:r)

      해당 컬럼의 값은 참조되는 테이블의 컬럼 데이터 중 하나와

      일치하거나 null을 가진다.

      

   3) Unique(uk:u)

      테이블 내에서 해당 컬럼의 값은 항상 유일해야 한다.

      

   4) Not null(nn:ck:c)

      해당 컬럼은 null을 포함할 수 없다.

      

   5) Check(ck:c)

      해당 컬럼에 저장 가능한 데이터의 조건이나 값의 범위를 지정한다.


테이블 레벨에서 제약조건 부여  -> 권장!!

컬럼 레벨에서 제약조건 부여

반응형

'Database' 카테고리의 다른 글

[SQL 튜닝] 1. 실행계획(Execution plan)  (2) 2019.04.22
오라클 다중 WHERE조건  (0) 2018.06.25
JOIN (조인)  (0) 2018.01.12
오라클 SQL Developer 2018.01.09  (0) 2018.01.09
오라클 SQL Developer 2018.01.05  (0) 2018.01.09
반응형

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

                        --■■■ JOIN (조인) ■■■--

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

-- 덩치가 큰 테이블은 무겁고 효율적이지 않기 때문에 테이블을 나눈다

-- 나누는 행위를 정규화를 통해 실시함


-- 1. SQL 1992 CODE

SELECT *

FROM EMP;


SELECT *

FROM DEPT;



SELECT *

FROM EMP,DEPT;

--> CROSS JOIN → 수학에서 말하는 데카르트 곱(Cartersian Product)

--  두 테이블을 합친 모든 경우의 수. 자주 사용되지는 않는다.


SELECT COUNT(*)

FROM EMP;

--==>> 14


SELECT COUNT(*)

FROM DEPT;

--==>> 4


SELECT COUNT(*)

FROM EMP,DEPT;

--==>> 56 = 14*4


-- Equi Join : 서로 정확히 같은 것끼리 결합

SELECT *

FROM EMP, DEPT

WHERE EMP.DEPTNO = DEPT.DEPTNO;


SELECT *

FROM EMP E, DEPT D

WHERE E.DEPTNO=D.DEPTNO;

--TABLE명에 별칭을 붙여 사용할 수 있다.


-- Non Equi join : 범위 안에 적합한 것들 끼리 결합

SELECT *

FROM SALGRADE;


SELECT *

FROM EMP;


SELECT *

FROM EMP E, SALGRADE S

WHERE E.SAL BETWEEN S.LOSAL AND S.HISAL;

--EMP TABLE의 급여가 SALGRADE TABLE의 LOW~HIGH까지의 범위안에 있는 것들만 보여줌



INSERT INTO EMP(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM) 

VALUES(7966,'RAY', 'CLERK', 7839, SYSDATE, 1000, 1000)

--==>>1 행 이(가) 삽입되었습니다.


COMMIT;


-- Equi join 시 (+) 사용방법

SELECT *

FROM EMP E, DEPT D

WHERE E.DEPTNO=D.DEPTNO (+);

--==>>7966 RAY CLERK 7839 2018-01-10 1000 1000



SELECT *

FROM EMP E, DEPT D

WHERE E.DEPTNO(+)=D.DEPTNO;

--==>> 40 OPERATIONS BOSTON



--※ (+) 가 없는 쪽 테이블의 데이터를 모두 먼저 메모리에 퍼올린 후 

--   (+) 가 있는 쪽 테이블의 데이터와 짝을 구성하는 과정을 통해 조회 결과를 종합.


SELECT *

FROM EMP E, DEPT D

WHERE E.DEPTNO(+)=D.DEPTNO(+);

--> 이와 같은 구문은 존재하지 않는다.

--==>>에러발생


--(+)가 없는쪽이 주인공 (+)가 없는 테이블 내용을 다 뿌린다음에 (+) 있는 것을 나열한다

--연결고리가 없을 시에는 NULL로 표시



-- 2. SQL 1999 CODE


-- CROSS JOIN

SELECT *

FROM EMP CROSS JOIN DEPT;



-- INNER JOIN

SELECT *

FROM EMP INNER JOIN DEPT

ON EMP.DEPTNO=DEPT.DEPTNO;


SELECT *

FROM EMP E JOIN DEPT D

ON E.DEPTNO=D.DEPTNO;

-->INNER JOIN의 경우 INNER의 키워드를 생략할 수 있다.

-->기존 조건을 작성하던 WHERE를 ON으로 대체


SELECT *

FROM EMP E JOIN SALGRADE S

ON E.SAL BETWEEN S.LOSAL AND S.HISAL;



-- OUTER JOIN

SELECT *

FROM EMP E LEFT OUTER JOIN DEPT D

ON E.DEPTNO=D.DEPTNO;


--> (+)가 오른쪽에 붙어 있는 결과와 같음


SELECT *

FROM EMP E RIGHT OUTER JOIN DEPT D

ON E.DEPTNO=D.DEPTNO;


--> (+)가 왼쪽에 붙어 있는 결과와 같음


SELECT *

FROM EMP E FULL OUTER JOIN DEPT D

ON E.DEPTNO=D.DEPTNO;


--> (+)를 양쪽에 붙인 결과 새로 생긴 문법 

-- OUTER JOIN도 OUTER 키워드를 생략할 수 있다.


SELECT *

FROM EMP E FULL JOIN DEPT D

ON E.DEPTNO=D.DEPTNO;


-- 위와 같이 조회한 결과에서

-- 직종이 MANAGER와 CLERK만 조회하고자 한다.


SELECT *

FROM EMP E JOIN DEPT D

ON E.DEPTNO=D.DEPTNO

AND JOB IN ('MANAGER','CLERK');

--  쿼리문을 이렇게 구성해도 조회는 가능하지만 권장하지 않는다.


SELECT *

FROM EMP E JOIN DEPT D

ON E.DEPTNO=D.DEPTNO                  -- JOIN(결합) 조건

WHERE JOB IN ('MANAGER','CLERK');     -- 레코드의 선택 조건


--○ 퀴즈

-- EMP 테이블과 DEPT 테이블을 활용하여

-- 직종이 MANAGER와 CLERK인 사원들의 

-- 부서번호, 부서명, 사원명, 직종명, 급여 항목으로 조회한다.

SELECT *

FROM EMP;


SELECT *

FROM DEPT;


--연결고리가 DEPTNO임을 알 수 있음


SELECT D.DEPTNO,D.DNAME,E.ENAME,E.JOB,E.SAL

FROM EMP E JOIN DEPT D

ON E.DEPTNO=D.DEPTNO

AND JOB IN ('MANAGER','CLERK');


--증복 컬럼과 같은 경우는 소속을 명시해주어야 한다.

--소속을 명시해 줄때는 부모 테이블것을 명시해 주어야한다.

--관계형 데이터베이스에서 부모와 자식을 결정짓는 것은 1 : 다 관계이다

--하나가 여럿을 담당하고 있을때 그 하나가 부모이다.


--중복컬럼이 아닌 나머지 컬럼들인 한가지 테이블에 존재하는 것들도 소속을 명시해주는 것이 바람직함

--소속테이블을 명시해주지 않으면 컬럼이 존재하더라도 나머지 테이블도 조회해야 하기 때문에

--리소스 소모가 심하다.



SELECT D.DEPTNO,D.DNAME,E.ENAME,E.JOB,E.SAL

FROM EMP E RIGHT JOIN DEPT D

ON E.DEPTNO=D.DEPTNO;

/*

10 ACCOUNTING CLARK MANAGER 2450

10 ACCOUNTING MILLER CLERK 1300

10 ACCOUNTING KING PRESIDENT 5000

20 RESEARCH JONES MANAGER 2975

20 RESEARCH SMITH CLERK 800

20 RESEARCH SCOTT ANALYST 3000

20 RESEARCH FORD ANALYST 3000

20 RESEARCH ADAMS CLERK 1100

30 SALES WARD SALESMAN 1250

30 SALES TURNER SALESMAN 1500

30 SALES ALLEN SALESMAN 1600

30 SALES JAMES CLERK 950

30 SALES MARTIN SALESMAN 1250

*/

SELECT E.DEPTNO,D.DNAME,E.ENAME,E.JOB,E.SAL

FROM EMP E RIGHT JOIN DEPT D

ON E.DEPTNO=D.DEPTNO;

/*

10 ACCOUNTING CLARK MANAGER 2450

10 ACCOUNTING MILLER CLERK 1300

10 ACCOUNTING KING PRESIDENT 5000

20 RESEARCH JONES MANAGER 2975

20 RESEARCH SMITH CLERK 800

20 RESEARCH SCOTT ANALYST 3000

20 RESEARCH FORD ANALYST 3000

20 RESEARCH ADAMS CLERK 1100

30 SALES WARD SALESMAN 1250

30 SALES TURNER SALESMAN 1500

30 SALES ALLEN SALESMAN 1600

30 SALES JAMES CLERK 950

30 SALES MARTIN SALESMAN 1250

30 SALES BLAKE MANAGER 2850

OPERATIONS

*/


--■■■ SELF JOIN (자기 조인) ■■■--


--○ EMP테이블의 정보를 다음과 같이 조회할 수 있도록 한다.


/*

사원번호   사원명    직종    관리자번호   관리자명    관리자직종명

  7369      SMITH     CLER      7902        FORD        ANALYST

  

*/

SELECT *

FROM EMP;


SELECT E.EMPNO"사원번호",E.ENAME"사원명",E.JOB"직종",E.MGR"관리자번호",EM.ENAME"관리자명",EM.JOB"관리자직종명"

FROM EMP E JOIN EMP EM

ON E.MGR = EM.EMPNO;



/*

  TBL_SAWON 테이블을 대상으로 다음과 같이 조회할 수 있도록 한다

  사원번호, 사원명, 주민번호, 성별, 현재나이, 입사일, 정년퇴직일, 근무일수, 남은일수, 급여, 보너스

  단 현재나이는 한국나이 계산법에 따라 연산을 수행한다.

  또한, 정년퇴직일은 해당 직원의 나이가 한국나이로 60세가 되는 해의 그 직원의 입사 월, 일로 한다.

  그리고 보너스는 1000일 이상 2000일 미만 근무한 사원은 그 사원이 받는 급여의 30%로 하고

  2000일 이상 근무한 사원은 그 사원이 받는 급여의 50%로 한다.

  */


SELECT *

FROM TBL_SAWON;


SELECT SANO "사원번호", SANAME"사원명", JUBUN"주민번호"

    , DECODE(SUBSTR(JUBUN,7,1), '1','남자','4','남자', '여자') "성별"


    , CASE WHEN SUBSTR(JUBUN, 7, 1) IN ('1', '2') 

                    THEN EXTRACT(YEAR FROM SYSDATE) - (TO_NUMBER(SUBSTR(JUBUN, 1, 2)) + 1899)

                    WHEN SUBSTR(JUBUN, 7, 1) IN ('3', '4')

                    THEN EXTRACT(YEAR FROM SYSDATE) - (TO_NUMBER(SUBSTR(JUBUN, 1, 2)) + 1999)

                    ELSE 0

               END"현재나이"

    , HIREDATE "입사일"

    , TO_CHAR(ADD_MONTHS(SYSDATE,(60-(CASE WHEN SUBSTR(JUBUN, 7, 1) IN ('1', '2') 

                    THEN EXTRACT(YEAR FROM SYSDATE) - (TO_NUMBER(SUBSTR(JUBUN, 1, 2)) + 1899)

                    WHEN SUBSTR(JUBUN, 7, 1) IN ('3', '4')

                    THEN EXTRACT(YEAR FROM SYSDATE) - (TO_NUMBER(SUBSTR(JUBUN, 1, 2)) + 1999)

                    ELSE 0

               END))*12) ,'YYYY')||'-'||TO_CHAR(HIREDATE,'MM-DD') "정년퇴직일"    

    , TRUNC(SYSDATE - HIREDATE)"근무일수"


    , TRUNC(TO_DATE(TO_CHAR(ADD_MONTHS(SYSDATE,(60-(CASE WHEN SUBSTR(JUBUN, 7, 1) IN ('1', '2') 

                    THEN EXTRACT(YEAR FROM SYSDATE) - (TO_NUMBER(SUBSTR(JUBUN, 1, 2)) + 1899)

                    WHEN SUBSTR(JUBUN, 7, 1) IN ('3', '4')

                    THEN EXTRACT(YEAR FROM SYSDATE) - (TO_NUMBER(SUBSTR(JUBUN, 1, 2)) + 1999)

                    ELSE 0

               END))*12) ,'YYYY')||'-'||TO_CHAR(HIREDATE,'MM-DD'), 'YYYY-MM-DD') - SYSDATE) "남은일수"

    , SAL"급여"

    , CASE WHEN TRUNC(SYSDATE-HIREDATE)=2000 THEN SAL*0.5

           WHEN TRUNC(SYSDATE-HIREDATE)=1000 THEN SAL*0.3

     ELSE 0

      END "보너스"

FROM TBL_SAWON;


--○ 문제

--  EMPLOYEES, DEPARTMENTS, JOBS, LOCATIONS, COUNTRIES, REGIONS


--  이 6개의 테이블을 대상으로 직원들의 정보를 다음과 같이 조회한다.

--  FIRST_NAME, LAST_NAME, JOB_TITLE, DEPARTMENT_NAME, CITY, COUNTRY_NAME, REGION_NAME



SELECT EM.FIRST_NAME, EM.LAST_NAME, JOBS.JOB_TITLE, DE.DEPARTMENT_NAME, LO.CITY, COUN.COUNTRY_NAME, RE.REGION_NAME

FROM EMPLOYEES EM LEFT JOIN DEPARTMENTS DE

ON EM.DEPARTMENT_ID = DE.DEPARTMENT_ID

  JOIN JOBS

  ON EM.JOB_ID=JOBS.JOB_ID

  LEFT JOIN LOCATIONS LO

  ON DE.LOCATION_ID=LO.LOCATION_ID

  LEFT JOIN COUNTRIES COUN

  ON COUN.COUNTRY_ID=LO.COUNTRY_ID

  LEFT JOIN REGIONS RE

  ON RE.REGION_ID=COUN.REGION_ID

     ;

반응형

'Database' 카테고리의 다른 글

오라클 다중 WHERE조건  (0) 2018.06.25
무결성 (Integrity)  (0) 2018.01.12
오라클 SQL Developer 2018.01.09  (0) 2018.01.09
오라클 SQL Developer 2018.01.05  (0) 2018.01.09
데이터베이스와 DBMS 개요  (0) 2018.01.09
반응형

SELECT USER

FROM DUAL;


--○ TBL_EMP 테이블에서 모든 사원들의 

--   사원번호, 사원명, 급여, 커미션, 연봉 정보를 조회한다.

--   단, 급여(SAL)는 매월 지급한다.

--   수당(COMM)은 1회/년 지급한다.


ALTER TABLE TBL_EMP

ADD MONEY NUMBER(10);


ALTER TABLE TBL_EMP DROP COLUMN MONEY;


SELECT EMPNO 사원번호, ENAME 사원명, SAL 급여, COMM 커미션, (SAL*12)+(COMM) 연봉

FROM TBL_EMP;

--> 이와 같이 연봉을 연산하여 조회할 경우 수당(COMM)이 NULL인 직원들은 연봉까지도 NULL로 연산되는 것을

--  확인 할 수 있다.


SELECT EMPNO 사원번호, ENAME 사원명, SAL 급여, COMM 커미션, (SAL*12) 연봉

FROM TBL_EMP;

--> 그렇다고 수당(COMM)을 연산 대상에서 제외시키거나 

--  0으로 가정하고 연산을 수행할 경우 수당(COMM)이 존재하는 직원들의 연산 결과가 잘못되어 처리된다.


-- ○NVL() 함수


SELECT NULL "①", NVL(NULL,0)"②",NVL(2,0)"③"

FROM DUAL;

--==>> (NULL) 0 2

--> 첫 번째 파라미터 값이 NULL 이면, 두 번째 파라미터 값을 적용한다.

--  첫 번째 파라미터 값이 NULL 이 아니면, 그 값을 그대로 적용한다.


SELECT ENAME, NVL(COMM,0)

FROM TBL_EMP;


SELECT EMPNO 사원번호, ENAME 사원명, SAL 급여, NVL(COMM,0) 커미션, (SAL*12)+(NVL(COMM,0)) 연봉

FROM TBL_EMP;

--==>>

/*

7369 SMITH 800 0 9600

7499 ALLEN 1600 300 19500

7521 WARD 1250 500 15500

7566 JONES 2975 0 35700

7654 MARTIN 1250 1400 16400

7698 BLAKE 2850 0 34200

7782 CLARK 2450 0 29400

7788 SCOTT 3000 0 36000

7839 KING 5000 0 60000

7844 TURNER 1500 0 18000

7876 ADAMS 1100 0 13200

7900 JAMES 950 0 11400

7902 FORD 3000 0 36000

7934 MILLER 1300 0 15600

*/


--○ NVL2()

SELECT NVL2(NULL,10,20)"①" , NVL2(0,10,20)"②"

FROM DUAL;

--==>>20 10


/*

첫 번째 인자 값이 NULL이면 세 번째 인자 값을 반환하고

첫 번째 인자 값이 NULL이 아니면 두번째 인자 값을 반환한다.


즉 COMM이 NULL인 직원들은 10만큼 추가 수당을 지급

이라는 조건이 붙은 상황일때 사용한다.


*/


--○ TBL_EMP 테이블에서 COMM 컬럼의 값이 NULL 이 아니면 3000,

--   NULL이면 4000으로 특별 수당을 지급하는 상황이다.

--   이에 대한 연산 결과를 조회할 수 있도록 한다.

--   사원명 급여, 수당, 특별수당 항목을 조회한다.


SELECT ENAME "사원명", SAL "급여", NVL(COMM,0) "수당", NVL2(COMM,3000,4000) "특별수당"

FROM TBL_EMP;


/*

SMITH 800 0 4000

ALLEN 1600 300 3000

WARD 1250 500 3000

JONES 2975 0 4000

MARTIN 1250 1400 3000

BLAKE 2850 0 4000

CLARK 2450 0 4000

SCOTT 3000 0 4000

KING 5000 0 4000

TURNER 1500 0 3000

ADAMS 1100 0 4000

JAMES 950 0 4000

FORD 3000 0 4000

MILLER 1300 0 4000

*/




--○ TBL_EMP 테이블에서 모든 사원들의 

--   사원번호, 사원명, 급여, 커미션, 연봉 정보를 조회한다.

--   단, 급여(SAL)는 매월 지급한다.

--   수당(COMM)은 1회/년 지급한다.

--   또한, NVL2() 함수를 활용하여 처리한다.


--○ NVL2()를 이용해서 연봉 구하기

--  첫 번째 매개변수가 NULL이면 세번째 매개변수를 반환

--  첫 번재 매개변수가 NULL이 아니면 두 번째 매개변수를 반환


SELECT EMPNO 사원번호, ENAME 사원명, SAL 급여, NVL(COMM,0) 커미션, (SAL*12)+(NVL2(COMM,COMM,0)) 연봉

FROM TBL_EMP;


/*

==========================================

■■■ NVL / NVL2 정리 ■■■

==========================================

-- NVL(매개변수1, 매개변수2)

   매개변수1이 NULL이면 매개변수2를 반환

   매개변수1이 NULL이 아니면 매개변수1을 반환


-- NVL2(매개변수1, 매개변수2, 매개변수3)

   매개변수1이 NULL이면 매개변수3을 반환

   매개변수1이 NULL이 아니면 매개변수2를 반환

*/


--○ COALESCE()  NULL처리 함수

--> 맨 앞부터 차례로 값이 NULL 이 아니면 적용(반환)하고

--  NULL 인 경우에는 다음 파라미터를 확인하는 연산으로 넘어간다.


SELECT COALESCE(NULL,NULL,NULL,NULL,10)"첫 번째 컬럼"

      , COALESCE(10,20,30)"두 번째 컬럼"

FROM DUAL;



-- ※모든 경우의 수를 확인할 수 있다.

-- TBL_EMP 테이블 데이터 수정


UPDATE TBL_EMP 

SET SAL=NULL

WHERE EMPNO=7521;

--==>1행이 업데이트 되었습니다.


SELECT *

FROM TBL_EMP;


COMMIT;

--==>커밋 완료.


--○ TBL_EMP 테이블에서 연봉에 대한 연산 결과가 NULL 이 나오는 경우는

--   급여(SAL)가 NULL, 혹은 수당(COMM)이 NULL, 또는 둘 다 NULL

--   모든 경우를 고려하여 연봉을 조회할 수 있도록 쿼리문을 구성한다.

--   COALESECE() 함수를 사용하여 사원번호, 사원명, 급여, 수당, 연봉을 조회한다.

--   단 연봉은 급여*12+수당 으로 연산처리 한다.


SELECT EMPNO "사원번호", ENAME "사원명", COALESCE(SAL,0) "급여", COALESCE(COMM,0) "수당", COALESCE(SAL*12,0)+COALESCE(COMM,0) "연봉"

FROM TBL_EMP;


SELECT EMPNO "사원번호", ENAME "사원명", COALESCE(SAL,0) "급여", COALESCE(COMM,0) "수당", COALESCE(SAL*12+COMM,SAL*12,COMM,0) "연봉"

FROM TBL_EMP;


--둘 중에 하나가 NULL이라고 가질 수 있는 모든 경우의 수를 생각하여

--하나씩 경우의 수를 풀어나간다.

--즉 SAL*12가 NULL일 경우 / COMM이 NULL일 경우 / 둘다 NULL일 경우를 생각!



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


--※ 날짜에 대한 세션 설정 변경


ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS';

--○ 현재 시간(날짜)을 조회하는 함수

SELECT SYSDATE, CURRENT_DATE, LOCALTIMESTAMP

FROM DUAL;

--사용 빈도는 SYSDATE가 가장 높음

--==>>2018-01-09 10:05:01



--○ 컬럼과 컬럼의 연결(『||』)

SELECT '김선규'||'생선대갈'

FROM DUAL;



SELECT '김선규'||10||SYSDATE

FROM DUAL;

--==>>김선규102018-01-09 10:11:15

--내부적으로 오라클이 형변환을 문자열로 변환해서 문자열끼리 이어주고 출력해줌

--즉 문자열 || 숫자 || 날짜 를

--   문자열 || 문자열 || 문자열 타입으로 변환하여 컬럼끼리 연결해줌


--※ 오라클에서는 문자열로 형 변환의 과정 없이

--   『||』만 넣어주면 간단히 컬럼과 컬럼을 연결하는 것이 가능하다.

--    MSSQL 에서는 모든 문자열을 CONVERT 해야한다.


SELECT *

FROM TBL_EMP;


--○ TBL_EMP 테이블의 정보를 활용하여

--   EX) SMITH의 현재 연봉은 9600인데 희망 연봉은 19200이다.

--       ALLEN의 현재 연봉은 19500인데 희망 연봉은 39000이다.

--   이와 같은 형식으로 조회할 수 있도록 한다.

SELECT ENAME||'의 현재 연봉은'||COALESCE(SAL*12+COMM,SAL*12,COMM,0)||'인데 희망 연봉은'||COALESCE(SAL*12+COMM,SAL*12,COMM,0)*2||'이다.'

FROM TBL_EMP;


DESC TBL_EMP;


ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD';


SELECT ENAME, HIREDATE

FROM TBL_EMP;


SELECT ENAME||'의 입사일은 '||HIREDATE||'입니다. 그리고 급여는 '||NVL(SAL,0)||'입니다.'

FROM TBL_EMP;

/*

SMITH의 입사일은 1980-12-17입니다. 그리고 급여는 800입니다.

ALLEN의 입사일은 1981-02-20입니다. 그리고 급여는 1600입니다.

WARD의 입사일은 1981-02-22입니다. 그리고 급여는 0입니다.

JONES의 입사일은 1981-04-02입니다. 그리고 급여는 2975입니다.

MARTIN의 입사일은 1981-09-28입니다. 그리고 급여는 1250입니다.

BLAKE의 입사일은 1981-05-01입니다. 그리고 급여는 2850입니다.

CLARK의 입사일은 1981-06-09입니다. 그리고 급여는 2450입니다.

SCOTT의 입사일은 1987-07-13입니다. 그리고 급여는 3000입니다.

KING의 입사일은 1981-11-17입니다. 그리고 급여는 5000입니다.

TURNER의 입사일은 1981-09-08입니다. 그리고 급여는 1500입니다.

ADAMS의 입사일은 1987-07-13입니다. 그리고 급여는 1100입니다.

JAMES의 입사일은 1981-12-03입니다. 그리고 급여는 950입니다.

FORD의 입사일은 1981-12-03입니다. 그리고 급여는 3000입니다.

MILLER의 입사일은 1982-01-23입니다. 그리고 급여는 1300입니다.

*/



/*

SMITH'S 입사일은 1980-12-17입니다. 그리고 급여는 800입니다.

ALLEN'S 입사일은 1981-02-20입니다. 그리고 급여는 1600입니다.

WARD'S 입사일은 1981-02-22입니다. 그리고 급여는 0입니다.

                      :

와 같이 출력하라.

*/


SELECT ENAME||'''s 입사일은 '||HIREDATE||'입니다. 그리고 급여는 '||NVL(SAL,0)||'입니다.'

FROM TBL_EMP;


--※ 오라클은 문자열 영역 안에서 『'』(홑따옴표) 두개가 하나를 표현하는 구조로 기능한다.


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


--○ 오라클에서 데이터의 값 만큼은 반드시 대소문자 구분을 엄격하게 처리한다.



SELECT EMPnO, EnAME, joB

FROM Tbl_EmP

WHERE job='CLERK';

/*

7369 SMITH CLERK

7876 ADAMS CLERK

7900 JAMES CLERK

7934 MILLER CLERK

*/


SELECT EMPnO, EnAME, joB

FROM Tbl_EmP

WHERE job='CLerk';

--==>>조회 결과 없음



--○ UPPER() , LOWER(), INITCAP() 첫글자만 대문자로 처리


SELECT 'oRAcLE',UPPER('oRAcLE'),LOWER('oRAcLE'),INITCAP('oRAcLE')

FROM DUAL;


--주로 WHERE조건절에서 사용되곤 한다


SELECT EMPnO, EnAME, joB

FROM Tbl_EmP

WHERE UPPER(job)=UPPER('CLerk');



SELECT EMPnO, EnAME, joB

FROM Tbl_EmP

WHERE LOWER(job)=LOWER('CLerk');


SELECT EMPnO, EnAME, joB

FROM Tbl_EmP

WHERE INITCAP(job)=INITCAP('CLerk');



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

--○ TBL_EMP테이블에서 입사일이 1981년 9월 28일 입사한 직원의

--   사원명, 직종명, 입사일 항목을 조회한다.


SELECT ENAME "사원명",JOB "직종명",HIREDATE "입사일"

FROM TBL_EMP

WHERE HIREDATE='1981-09-28';

--==>>MARTIN SALESMAN 1981-09-28

--상황에 따라 여건에 따라 형변환이 달라지기 때문에 믿으면 안된다

--따라서 이러한 쿼리문은 잘못된 것이다.


DESC TBL_EMP;

--==>>HIREDATE   DATE         


SELECT ENAME "사원명",JOB "직종명",HIREDATE "입사일"

FROM TBL_EMP

WHERE HIREDATE=TO_DATE('1981-09-28','YYYY-MM-DD');


--'1981-09-28' -> '1981-09-28'의 문자열

--TO_DATE('1981-09-28','YYYY-MM-DD')안에 넣어주면 -> 1981년 9월 28일이라는 날짜형


--'2018-01-09 10:47:10' -> '2018-01-09 10:47:10'의 문자열

-- TO_DATE('2018-01-09 10:47:10','YYYY-MM-DD HH24:MI;SS') -> 2018년 1월 9일 10시 47분 10초라는 날짜형


--○ TBL_EMP 테이블에서 입사잉ㄹ이 1981년 9월 28일 이후로 입사한 직원의

--   사원번호 직원명 입사일 항목을 조회한다.


SELECT EMPNO, ENAME, HIREDATE

FROM TBL_EMP

WHERE HIREDATE>=TO_DATE('1981-09-28','YYYY-MM-DD');


--○ TBL_EMP 테이블에서 입사일이 1981년 4월 2일부터 1981년 9월 28일 사이에 입사한 직원의

--   사원번호, 사원명, 입사일 항목을 조회한다.


SELECT EMPNO, ENAME, HIREDATE

FROM TBL_EMP

WHERE HIREDATE>=TO_DATE('1981-04-02','YYYY-MM-DD') AND HIREDATE<=TO_DATE('1981-09-28','YYYY-MM-DD');


--○ 컬럼명 BETWEEN a(조건) AND b(조건)

--   숫자 / 문자 에도 통용된다!

SELECT EMPNO, ENAME, HIREDATE

FROM TBL_EMP

WHERE HIREDATE BETWEEN TO_DATE('1981-04-02','YYYY-MM-DD') AND TO_DATE('1981-09-28','YYYY-MM-DD');

/*

7566 JONES 1981-04-02

7654 MARTIN 1981-09-28

7698 BLAKE 1981-05-01

7782 CLARK 1981-06-09

7844 TURNER 1981-09-08

*/

SELECT *

FROM TBL_EMP

WHERE SAL BETWEEN 2000 AND 3000;

/*

7566 JONES MANAGER 7839 1981-04-02 2975 20

7698 BLAKE MANAGER 7839 1981-05-01 2850 30

7782 CLARK MANAGER 7839 1981-06-09 2450 10

7788 SCOTT ANALYST 7566 1987-07-13 3000 20

7902 FORD ANALYST 7566 1981-12-03 3000 20

*/


SELECT *

FROM TBL_EMP

WHERE ENAME BETWEEN 'C' AND 'S';

-->S까지만 검색을한다 

-- 그래서 SCOTT등은 검색이 안됨. 이름이 S이면 거기까지 검색이된다

-- 왜냐하면 사전식배열이기 때문이다.

-- 내부적으로는 ASCII코드 기반으로 변환되기 때문에 대소문자도 주의해야한다.


/* 

※ BETWEEN a AND b 는 날짜, 숫자, 문자 모두에 적용된다

   하지만 문자일 경우 아스키 코드 순서를 따르기 때문에 대문자가 앞에 있고 

   소문자가 뒤에있다는 배열과정의 순서를 주의해야 한다.

   또한, BETWEEN a AND b는 수행되는 시점에서 오라클 내부적으로는

   부등호 연산자의 형태로 바뀌어 연산된다.

   마지막으로 문자일 경우 사전식 배열과정의 순서를 주의해야한다.

*/

SELECT *

FROM TBL_EMP;

/*

7566 JONES MANAGER 7839 1981-04-02 2975 20

7654 MARTIN SALESMAN 7698 1981-09-28 1250 1400 30

7782 CLARK MANAGER 7839 1981-06-09 2450 10

7839 KING PRESIDENT 1981-11-17 5000 10

7900 JAMES CLERK 7698 1981-12-03 950 30

7902 FORD ANALYST 7566 1981-12-03 3000 20

7934 MILLER CLERK 7782 1982-01-23 1300 10

*/



--○ ASCII()

SELECT ASCII('A'), ASCII('Z'), ASCII('a'), ASCII('z')

FROM DUAL;

--==>>65 90 97 122


--○ TBL_EMP 테이블에서 직종이 SALESMAN과 CLERK인 사원의

--   사원명 직종명, 급여 항목을 조회한다.


SELECT ENAME, JOB , SAL

FROM TBL_EMP

WHERE JOB ='SALESMAN' OR JOB='CLERK';


SELECT ENAME, JOB , SAL

FROM TBL_EMP

WHERE JOB IN('SALESMAN'  ,'CLERK');



SELECT ENAME, JOB , SAL

FROM TBL_EMP

WHERE JOB =ANY('SALESMAN'  ,'CLERK');

--  =ANY는 OR연산자와 같다.

--  =ALL은 AND연산자와 같음.


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


--○ 테이블 생성(TBL_SAWON)


CREATE TABLE TBL_SAWON

( SANO      NUMBER(4) PRIMARY KEY

, SANAME    VARCHAR2(40)

, JUBUN     CHAR(13)

, HIREDATE  DATE DEFAULT SYSDATE  --자동으로 현재 시간을 입력

, SAL       NUMBER    --길이를 명시하지 않으면 숫자표현의 최대값 사용

);

--CHAR를 단위를 쓰지 않고 표현하면 문자의 최소값 즉 1개만 사용

--CHAR에서 최대값을 쓰려면 CHAR(2000)이라 써야함

--즉 NUMBER와 CHAR 매개변수를 생략하면 의미가 반대가 된다.

--==>>Table TBL_SAWON이(가) 생성되었습니다.


--○데이터 입력

INSERT INTO TBL_SAWON VALUES(1001, '명소희', '9302272234567', TO_DATE('2017-03-02','YYYY-MM-DD'), 4000000);

INSERT INTO TBL_SAWON VALUES(1002, '임미영', '9310092234567', TO_DATE('2017-03-02','YYYY-MM-DD'), 4000000);

INSERT INTO TBL_SAWON VALUES(1003, '조태희', '9010271234567', TO_DATE('2017-03-02','YYYY-MM-DD'), 4000000);

INSERT INTO TBL_SAWON VALUES(1004, '김선규', '9202231234567', TO_DATE('2017-11-13','YYYY-MM-DD'), 4000000);

INSERT INTO TBL_SAWON VALUES(1005, '서운성', '9307151234567', TO_DATE('2017-11-13','YYYY-MM-DD'), 4000000);

INSERT INTO TBL_SAWON VALUES(1006, '박기범', '9002271234567', TO_DATE('2017-11-13','YYYY-MM-DD'), 4000000);

INSERT INTO TBL_SAWON VALUES(1007, '최진규', '9105071234567', TO_DATE('2017-11-13','YYYY-MM-DD'), 4000000);

INSERT INTO TBL_SAWON VALUES(1008, '김준협', '9212101234567', TO_DATE('2017-11-13','YYYY-MM-DD'), 4000000);

INSERT INTO TBL_SAWON VALUES(1009, '정승우', '9304211234567', TO_DATE('2017-11-13','YYYY-MM-DD'), 4000000);

INSERT INTO TBL_SAWON VALUES(1010, '오승우', '9112271234567', TO_DATE('2017-11-13','YYYY-MM-DD'), 4000000);

INSERT INTO TBL_SAWON VALUES(1011, '선동렬', '0212273234567', TO_DATE('2018-01-02','YYYY-MM-DD'), 2000000);

INSERT INTO TBL_SAWON VALUES(1012, '선우용녀', '0301024234567', TO_DATE('2018-01-02','YYYY-MM-DD'), 2000000);

INSERT INTO TBL_SAWON VALUES(1013, '선우선', '0405064234567', TO_DATE('2018-01-02','YYYY-MM-DD'), 2000000);

INSERT INTO TBL_SAWON VALUES(1014, '스윙스', '0505053234567', TO_DATE('2018-01-02','YYYY-MM-DD'), 2000000);


SELECT *

FROM TBL_SAWON;


COMMIT;

--==>>커밋 완료.


--○ TBL_SAWON 테이블에 존재하는 『최진규』사원의 정보를 조회한다.


SELECT *

FROM TBL_SAWON

WHERE SANAME='최진규';

--==>>1007 최진규 9105071234567 17/11/13 4000000

SELECT *

FROM TBL_SAWON

WHERE SANAME LIKE '최진규';


--※ LIKE 동사 : 좋아하다

--        부사 : ~~처럼 / ~~와 같이


--※ WILD CHARACTER --> 『%』

--   『LIKE』 키워드와 함께 사용되는 『%』 는 모든 글자를 의미하고

--   『LIKE』 키워드와 함께 사용되는 『_』 는 아무 글자 1개를 의미한다.


--○ TBL_SAWON 테이블에서 성이 『김』씨인 사원들의

--   사원명, 주민번호, 급여를 조회한다.


SELECT SANAME, JUBUN, SAL

FROM TBL_SAWON

WHERE SANAME = '김';

--==>> 조회결과 없음


SELECT SANAME, JUBUN, SAL

FROM TBL_SAWON

WHERE SANAME = '김__';

--> 이름이 김__인 사원을 찾아라 존재하지 않음!


SELECT SANAME, JUBUN, SAL

FROM TBL_SAWON

WHERE SANAME LIKE '김__';

--> 김 ㅇ ㅇ 이름이 총 3글자인 사원만 검색된다

--==>>김선규 9202231234567 4000000

--==>>김준협 9212101234567 4000000


SELECT SANAME, JUBUN, SAL

FROM TBL_SAWON

WHERE SANAME LIKE '김%';

--> 김 ~~ 인 김씨인 모든 사원이 검색된다(글자수 제한이 없음) 김 도 찾아짐

--==>>김선규 9202231234567 4000000

--==>>김준협 9212101234567 4000000


--○ TBL_SAWON 테이블에서 이름이 『승우』인 사원의

--   사원명, 주민번호, 급여 항목을 조회한다.

SELECT SANAME, JUBUN, SAL

FROM TBL_SAWON

WHERE SANAME LIKE '%승우';



--○ TBL_SAWON 테이블에서 이름의 두 번째 글자가 『선』인 사원의

--   사원명, 주민번호, 급여 항목을 조회한다.

SELECT SANAME, JUBUN, SAL

FROM TBL_SAWON

WHERE SANAME LIKE '_선%';



--○ TBL_SAWON 테이블에서 이름에서 성이 『선』인 사원의

--   사원명, 주민번호, 급여 항목을 조회한다.


/*

=========================================================

                ■■■■ 결론 ■■■■

=========================================================

결론부터 말하면 불가능하다.

※ 데이터베이스 설계 시 성과 이름을 분리해서 처리해야 할 업무 계획이 있다면

테이블 구성(생성) 과정에서 성 컬럼과 이름 컬럼을 분리하여 구성해야 한다!

*/



--○ TBL_SAWON 테이블에서 여직원들의 사원명, 주민번호, 급여 항목을 조회한다.

SELECT SANAME, JUBUN, SAL

FROM TBL_SAWON

WHERE JUBUN LIKE '______2%' OR JUBUN LIKE '______4%';



SELECT SANAME, JUBUN, SAL

FROM TBL_SAWON

WHERE SUBSTR(JUBUN,7,1) LIKE '2' OR SUBSTR(JUBUN,7,1) LIKE '4';


--○ 테이블 생성

CREATE TABLE TBL_WATCH

( WATCHNAME   VARCHAR2(40)

, BIGO        VARCHAR2(100)

);

--==>>Table TBL_WATCH이(가) 생성되었습니다.


INSERT INTO TBL_WATCH VALUES('금시계', '순금 99.9% 함유된 최고급 시계');

INSERT INTO TBL_WATCH VALUES('은시계', '고객 만족도 99.99점 획득 시계');

--==>>2 행 이(가) 삽입되었습니다

--○ 커밋

COMMIT;



UPDATE TBL_WATCH

SET BIGO='순금 99.99% 함유된 최고급 시계'

WHERE BIGO='순금 99.9% 함유된 최고급 시계';


--○ TBL_WATCH 테이블의 BIGO(비고) 컬럼에 

--   『99.99%』라는 글자가 들어있는 행의 정보를 조회한다.

SELECT *

FROM TBL_WATCH

WHERE BIGO LIKE'%99.99%%';

-->쿼리문에 사용한 모든 %를 WILD CHARACTER로 인식하기 때문에

-- 원하는 결과를 얻을 수 없는 상황이다.

-- 즉, BIGO 컬럼의 데이터 중 문자열에 99.99가 포함된 행의 정보 조회



SELECT *

FROM TBL_WATCH

WHERE BIGO LIKE '%99.99/%%' ESCAPE '/';


SELECT *

FROM TBL_WATCH

WHERE BIGO LIKE '%99.99#%%' ESCAPE '#';



--※ ESCAPE로 설정한 문자는 와일드 캐릭터에서 탈출시켜라!

--   즉 탈출시키고 싶은 문자 앞에 붙인다!

--   일반적으로 ESCAPE로 설정하는 한 문자는 

--   사용 빈도가 비교적 적은 특수문자로 설정한다!




--■■■ 정렬(ORDER BY) ■■■--

/*

FROM

WHERE

GROUP BY

HAVING

SELECT

ORDER BY

순으로 파싱이 일어남


ORDER BY는 리소스 소모가 크므로 사용할 때 주의해야 한다.

ASC : 오름차순(DEFAULT 값이므로 생략가능)

DESC : 내림차순(생략 불가능)

*/


SELECT ENAME"사원명",DEPTNO"부서번호",JOB"직종",SAL"급여",

       (SAL*12)+NVL(COMM,0)"연봉"

FROM EMP;



SELECT ENAME"사원명",DEPTNO"부서번호",JOB"직종",SAL"급여",

       (SAL*12)+NVL(COMM,0)"연봉"

FROM EMP

ORDER BY DEPTNO ASC;   -- 정렬 기준 컬럼 : DEPTNO(부서번호)

                       -- ASC : 오름차순(생략가능 DEFAULT 값) 

SELECT ENAME"사원명",DEPTNO"부서번호",JOB"직종",SAL"급여",

       (SAL*12)+NVL(COMM,0)"연봉"

FROM EMP

ORDER BY DEPTNO DESC;  -- DESC : 내림차순



DESC EMP; --DESC는 위치가 어디에 쓰이는 지에 따라 다르게 사용된다.


SELECT ENAME"사원명",DEPTNO"부서번호",JOB"직종",SAL"급여",

       (SAL*12)+NVL(COMM,0)"연봉"

FROM EMP

ORDER BY 부서번호 DESC;  -- DESC : 내림차순


SELECT ENAME"사원명",DEPTNO"부서번호",JOB"직종",SAL"급여",

       (SAL*12)+NVL(COMM,0)"연봉"

FROM EMP

ORDER BY 2 DESC;  -- 2번째 컬럼을 의미(부서번호) 오라클은 1부터 시작

                  --※ 테이블을 구성하는 컬럼 순서가 아닌 

                  --   SELCET문에서의 2번째 컬럼을 의미한다

                  

--> ORDER BY절보다 SELECT가 먼저 실행되기 때문에

--  컬럼명 대신 ALIAS(별칭)을 사용하는 것도 가능하고,

--  SELECT 되는 컬럼의 순서를 사용하는 것도 가능하다.


SELECT ENAME"사원명",DEPTNO"부서번호",JOB"직종",SAL"급여",

       (SAL*12)+NVL(COMM,0)"연봉"

FROM EMP

ORDER BY 2,4;

--> 부서번호 내에서 급여가 오름차순 정렬


SELECT ENAME, DEPTNO, JOB,SAL

FROM EMP

ORDER BY 2,3,4 DESC;

--> DESC가 적용되는 것은 4번째 컬럼만 적용된다

--> 부서번호별 오름차순 -> 직종별 오름차순 -> 급여별 내림차순


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

            ---■■■ 문자열 처리 함수 ■■■---

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


--○ CONCAT()

-->  2개의 문자열을 연결하는 기능을 가진 함수(문자열 결합 함수)

--   단, 오직 두 개만 연결할 수 있다.


SELECT ENAME||JOB , CONCAT(ENAME,JOB)

FROM EMP;


SELECT CONCAT(CONCAT(ENAME,JOB),SAL)

FROM EMP;


--> 파이프와 마찬가지로 내부적인 형 변환이 일어나서 연결시켜준다.

--  CONCAT()은 문자열과 문자열을 연결하는 기능을 가진 함수이지만,

--  내부적으로 숫자나 날짜를 문자로 바꾸는 과정이 포함되어 있는 것이다.


--○ SUBSTR()

--> 문자열을 추출하는 기능을 가진 함수

--  첫 번째 파라미터 값은 대상 문자열(추출의 대상)

--  두 번째 파라미터 값은 추출을 시작하는 위치(1번째 인덱스부터 시작)

--  세 번째 파라미터 값은 추출할 문자열의 갯수

--  생략이 가능하며, 생략시 시작 위치부터 해당 문자열의 길이만큼! 추출한다)


SELECT ENAME, SUBSTR(ENAME,1,2)

FROM EMP;


--○ SUBSTRB()

--   바이트로 끊어서 문자열을 추출하는 함수

--   한글은 2바이트 이므로 주의해야한다!

--   인코딩 방식에도 주의할 것!!


SELECT SANAME, SUBSTRB(SANAME,1,2), SUBSTRB(SANAME,1,3)

FROM TBL_SAWON;


SELECT PARAMETER, VALUE

FROM SYS.NLS_DATABASE_PARAMETERS

WHERE PARAMETER = 'NLS_CHARACTERSET';

--==>>NLS_CHARACTERSET AL32UTF8

--기본적으로 사용하는 것은 UTF8


SELECT *

FROM TBL_SAWON;

--○ TBL_SAWON 테이블에서 남직원들의 사원명, 주민번호, 급여 항목을 조회한다.


SELECT SANAME, JUBUN, SAL

FROM TBL_SAWON

WHERE SUBSTR(JUBUN,7,1)='1' OR SUBSTR(JUBUN,7,1)='3';

--> SUBSTR은 문자열을 추출하는 것이므로 비교 대상도 문자열이여야지 정확하다!

--> 문자열 처리를 안해도 같은 값이 나오는 것은 자동 형변환때문


SELECT SANAME, JUBUN, SAL

FROM TBL_SAWON

WHERE SUBSTR(JUBUN,7,1) IN ('1','3');


--○ LENGTH(), LENGTHB()

SELECT LENGTH(ENAME), LENGTHB(ENAME)

FROM EMP;


--○ INSTR()

--> 첫 번재 파라미터 값에 해당하는 문자열에서(대상 문자열)

--  두 번째 파라미터 값에서 정의한 문자열이 등장하는 위치를 검색

--  세 번재 파라미터 값은 스캔을 시작하는 위치

--  네 번째 파라미터 값은 몇 번째 등장하는 지를 결정(1일때는 생략가능)


SELECT INSTR('oracle orahome biora','ora',1,1) --첫문자부터에서 1번째 ora가 등장하는 위치

      ,INSTR('oracle orahome biora','ora',1,2) --첫문자부터에서 2번째 ora가 등장하는 위치

      ,INSTR('oracle orahome biora','ora',2,1) --두번째문자에서 1번째 ora가 등장하는 위치

      ,INSTR('oracle orahome biora','ora',2)   --두번째문자에서 1번째 ora가 등장하는 위치(1은 생략 가능)

      ,INSTR('oracle orahome biora','ora',2,2) --두번째문자에서 2번째 ora가 등장하는 위치 문자열 처음부터 스캔한 값을 반환

FROM DUAL;



SELECT INSTR('나의 오라클 집으로오라 합니다','오라',1) --첫문자부터에서 1번째 ora가 등장하는 위치

      ,INSTR('나의 오라클 집으로오라 합니다','오라',2) --첫문자부터에서 2번째 ora가 등장하는 위치

      ,INSTR('나의 오라클 집으로오라 합니다','오라',10) --두번째문자에서 1번째 ora가 등장하는 위치

      ,INSTR('나의 오라클 집으로오라 합니다','오라',11)   --두번째문자에서 1번째 ora가 등장하는 위치(1은 생략 가능)

      ,INSTR('나의 오라클 집으로오라 합니다','오라',12) --두번째문자에서 2번째 ora가 등장하는 위치 문자열 처음부터 스캔한 값을 반환

FROM DUAL;


--> 한글과 상관없이 문자열 위치 기반으로 반환


-- INSTAR('대상문자열','찾을문자열',검색시작위치,몇 번째 등장하는지)


--○ REVERSE()

-- 문자열을 거꾸로 처리한 결과값을 반환한다.

-- 단, 한글은 사용할 수 없다.

SELECT 'ORACLE', REVERSE('ORACLE')

FROM DUAL;


SELECT '오라클', REVERSE('오라클')

FROM DUAL;

-->비트 연산 기반이므로 한글은 처리가 되지 않음.



/*

테이블명 : TBL_FILES

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

FILENO                   FILENAME

1                         C:\AAA\BBB\CCC\SALES.XXLS

2                         C:\AAA\STUDY.HWP

3                         C:\RESEARCH\WORK\WORK.TXT

4                         C:\TEST.PPTX

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


조회 결과


파일 번호       파일명

1               SALES.XXLS

2               STUDY.HWP

3               WORK.TXT

4               TEST.PPTX

*/



CREATE TABLE TBL_FILES

( FILENO      NUMBER

, FILENAME    VARCHAR2(100)

);



INSERT INTO TBL_FILES VALUES(1,'C:\AAA\BBB\CCC\SALES.XXLS');

INSERT INTO TBL_FILES VALUES(2,'C:\AAA\STUDY.HWP');

INSERT INTO TBL_FILES VALUES(3,'C:\RESEARCH\WORK\WORK.TXT');

INSERT INTO TBL_FILES VALUES(4,'C:\TEST.PPTX');


COMMIT;


--내 풀이

SELECT FILENO "파일번호", REVERSE(SUBSTR(REVERSE(FILENAME),1,INSTR(REVERSE(FILENAME),'\',1)-1)) "파일 명"

FROM TBL_FILES;



SELECT FILENO "파일번호", REVERSE(FILENAME)"거꾸로된 파일명"

      ,REVERSE(SUBSTR(REVERSE(FILENAME), 1, INSTR(REVERSE(FILENAME),'\')-1))

FROM TBL_FILES;




--○ LPAD(), RPAD()

-->  BYTE 수를 확보하여 왼쪽(오른쪽)부터 문자열로 채우는 기능을 가진 함수

SELECT 'ORACLE', LPAD('ORACLE',10,'*')

FROM DUAL;

--① 10BYTE 공간을 확보한다.( 두 번재 파라미터 값에 의해)

--② 확보한 공간에 'ORACLE'(첫번째 파라미터 값) 문자열을 담는다.

--③ 남아있는 BYTE 공간에 왼쪽부터(오른족부터) '*'(세번째 파라미터 값)로 채운다.


SELECT 'ORACLE', RPAD('ORACLE',10,'*')

FROM DUAL;

--==>>ORACLE ORACLE****


--○ LTRIM(), RTRIM()

SELECT 'ORAORAORACLEORACLE'

      , LTRIM('ORAORAORACLEORACLE','ORA')

      , LTRIM('ORAoRAORACLEORACLE','ORA')

      , LTRIM('ORAARAORACLEORACLE','ORA')

      , LTRIM('ORA ORAORACLEORACLE','ORA')

FROM DUAL;

--==>>ORAORAORACLEORACLE CLEORACLE oRAORACLEORACLE CLEORACLE ORAORACLEORACLE

--> 첫 번째 파라미터값에 해당하는 문자열을 대상으로

--  왼쪽부터(오른쪽부터) 연속적으로 두 번재 인자값과

--  같은 글자가 등장할 경우 제거한다.

--  완성형으로 처리되지 않는다. O 또는 R 또는 A가 있으면 잘라낸다.

--  실무적으로 공백을 제거할 대 많이 사용된다.


--○ TRANSLATE()

--   1 : 1로 바꿔준다!!

--   첫번째 매개변수에 대해 두번째 매개변수에 해당하는 순서에 맞게 세번째 매개변수로 바꿔준다(1:1)로

--   두번재 매개변수에 존재하지 않으면 바꾸지 않는다.


SELECT TRANSLATE('MY ORACLE SERVER', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')

FROM DUAL;

--==>>my oracle server


SELECT '010-2546-5187', TRANSLATE('010-2546-5187','0123456789','공일이삼사오육칠팔구')

FROM DUAL;

--==>>010-2546-5187 공일공-이오사육-오일팔칠



--○ REPLACE()

--   TRANSLATE와 다르게 뭉텅이로 바꿔주는 구조

--   일대일로 치환하지 않는다. 즉 완성형으로 처리

SELECT REPLACE('MY ORACLE SERVER','ORA','오라')

FROM DUAL;

--   대소문자 구분을 명확히 하며, 완성형으로 처리된다.

--   1 : 1로 사상되는 TRANSLATE() 함수와 비교해서 정리하자!



--■■■ 숫자형 함수 ■■■--


--○ ROUND()

-->  반올림을 처리하는 함수

-- 첫번째 인자값은 반올림할 숫자

-- 두번재 인자값은 표현할 자릿수!

--> 두번째 인자값이 2이면 소수점 2번째 자리까지 표현하라! -> 3번째에서 반올림

SELECT 48.678, ROUND(48.678,2)

              ,ROUND(48.678,0)  --정수부까지 표현 0은 생략가능!!

              ,ROUND(48.678)    --정수부까지 표현

              ,ROUND(48.678,-1) --10의자리까지 유효한 숫자를 표현

              ,ROUND(48.678,-2) --100의자리까지 유효한 숫자를 표현

FROM DUAL;


--○ TRUNC()

-->  절삭하는 함수


SELECT 48.678, TRUNC(48.678,2)

              ,TRUNC(48.678,0)

              ,TRUNC(48.678,-1)

FROM DUAL;


--○ MOD() 나머지 연산자(%)

SELECT MOD(5,2)   --5를 2로 나눈 나머지

FROM DUAL;

--==>1



--○ POWER() 제곱(^)

SELECT POWER(5,3)   --5^3

FROM DUAL;



--○ SQRT() 루트

SELECT SQRT(2)    --ROOT 2

FROM DUAL;



--○ LOG() 로그 함수 --> 오라클은 상용로그만 지원

--MSSQL은 자연로그까지 지원

SELECT LOG(2,100)

FROM DUAL;


--○ 삼각함수

--SIN(), COS(), TAN()

SELECT SIN(1), COS(1), TAN(1)

FROM DUAL;


--○ 삼각함수의 역함수(범위 : -1 ~ 1 )

SELECT ASIN(0.5),ACOS(0.5),ATAN(0.5)

FROM DUAL;


--○ SIGN() 부호, 서명, 특징

--> 연산 처리에 대한 결과값이 양수이면 1, 0이면 0, 음수이면 01을 반환한다.

SELECT SIGN(5-2), SIGN(5-5), SIGN(2-5)

FROM DUAL;


--○ ASCII(), CHR()

-- CHR은 아스키코드값을 문자로 반환해줌

SELECT ASCII('A'), CHR(65)

FROM DUAL;

--==>>65 A

--결과값에서 오른쪽 정렬이면 숫자

--결과값에서 왼쪽 정렬이면 문자


--■■■ 날짜 연산 ■■■--


ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS';

--==>>Session이(가) 변경되었습니다.


--※ 날짜연산의 기본단위는 DAY(일수)이다.

-- (2018-01-09 16:48:27) + 2  더하면 기본적으로 날자에 더해야한다


SELECT SYSDATE, SYSDATE+1 , SYSDATE-2

FROM DUAL;

--==>>2018-01-09 16:50:01  2018-01-10 16:49:40 2018-01-07 16:49:40


--시간 단위 연산

SELECT SYSDATE, SYSDATE+1/24, SYSDATE-2/24

FROM DUAL;

--==>>2018-01-09 16:50:41 2018-01-09 17:50:41 2018-01-09 14:50:41



--○ 문제

/*

  현재 시간과, 1일 2시간 3분 4초 후를 조회(출력)한다.

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

         현재 시간        |          연산 후 시간

    2018-01-09 16:50:41       2018-01-10 18:53:40


*/


SELECT SYSDATE "현재 시간", SYSDATE+1+2/24+3/(24*60)+4/(24*60*60)

FROM DUAL;




COMMIT;














반응형

'Database' 카테고리의 다른 글

오라클 다중 WHERE조건  (0) 2018.06.25
무결성 (Integrity)  (0) 2018.01.12
JOIN (조인)  (0) 2018.01.12
오라클 SQL Developer 2018.01.05  (0) 2018.01.09
데이터베이스와 DBMS 개요  (0) 2018.01.09
반응형

■ 주석

1줄 주석 : -- (블록 잡고 ctrl + /)                                --○ 새로운 개념

여러줄 주석 : /* ~ */                                               --==>> 결과값

  -->> 설명

--○ 현재 접속한 자신의 계정 확인


SELECT USER

FROM DUAL;

--==>> HR


--※ sys로 접속한 상태에서! 시작



--○ 사용자 계정 생성 및 패스워드 설정

create user scott

identified by tiger;

--==>>User SCOTT이(가) 생성되었습니다.


--○ 권한 부여

GRANT CONNECT,RESOURCE,UNLIMITED TABLESPACE TO SCOTT;

--==>>Grant을(를) 성공했습니다.

--테이블스페이스는 테이블들이 논리적으로 저장되는 공간


--○ 구조적인 변경

ALTER USER SCOTT DEFAULT TABLESPACE USERS;

--==>>User SCOTT이(가) 변경되었습니다.


--○ 구조적인 변경

ALTER USER SCOTT TEMPORARY TABLESPACE TEMP;

--==>>User SCOTT이(가) 변경되었습니다.


--지금부터 SCOTT으로 접속~~!

--CONNECT SCOTT/TIGER



-- 사용자 확인

SELECT USER

FROM DUAL;

--==>> SCOTT


--○ 테이블 생성(DEPT)

CREATE TABLE DEPT

(DEPTNO   NUMBER(2) CONSTRAINT PK_DEPT PRIMARY KEY

, DNAME   VARCHAR2(14) 

, LOC     VARCHAR2(13) 

);


--하나의 항목속성을 컬럼이라 부름

--==>>Table DEPT이(가) 생성되었습니다.



--○ 확인

SELECT *

FROM DEPT;


--○ 테이블 생성(EMP)

CREATE TABLE EMP

       (EMPNO NUMBER(4) CONSTRAINT PK_EMP PRIMARY KEY

       ,  ENAME VARCHAR2(10)

       ,  JOB VARCHAR2(9)

       ,  MGR NUMBER(4)

       ,  HIREDATE DATE

       ,  SAL NUMBER(7,2)

       ,  COMM NUMBER(7,2)

       ,  DEPTNO NUMBER(2) CONSTRAINT FK_DEPTNO REFERENCES DEPT

       );

--==>>Table EMP이(가) 생성되었습니다.


--○ 확인

SELECT *

FROM EMP;


--○ 데이터 입력(DEPT TABLE)

--약식 구문으로 입력하고 있으나 권장하지는 않음

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');

--==>> 4행이 삽입되었습니다.


--○ 데이터 입력(EMP TABLE)


INSERT INTO EMP VALUES

(7369,'SMITH','CLERK',7902,to_date('17-12-1980','dd-mm-yyyy'),800,NULL,20);

INSERT INTO EMP VALUES

(7499,'ALLEN','SALESMAN',7698,to_date('20-2-1981','dd-mm-yyyy'),1600,300,30);

INSERT INTO EMP VALUES

(7521,'WARD','SALESMAN',7698,to_date('22-2-1981','dd-mm-yyyy'),1250,500,30);

INSERT INTO EMP VALUES

(7566,'JONES','MANAGER',7839,to_date('2-4-1981','dd-mm-yyyy'),2975,NULL,20);

INSERT INTO EMP VALUES

(7654,'MARTIN','SALESMAN',7698,to_date('28-9-1981','dd-mm-yyyy'),1250,1400,30);

INSERT INTO EMP VALUES

(7698,'BLAKE','MANAGER',7839,to_date('1-5-1981','dd-mm-yyyy'),2850,NULL,30);

INSERT INTO EMP VALUES

(7782,'CLARK','MANAGER',7839,to_date('9-6-1981','dd-mm-yyyy'),2450,NULL,10);

INSERT INTO EMP VALUES

(7788,'SCOTT','ANALYST',7566,to_date('13-7-1987','dd-mm-yyyy'),3000,NULL,20);

INSERT INTO EMP VALUES

(7839,'KING','PRESIDENT',NULL,to_date('17-11-1981','dd-mm-yyyy'),5000,NULL,10);

INSERT INTO EMP VALUES

(7844,'TURNER','SALESMAN',7698,to_date('8-9-1981','dd-mm-yyyy'),1500,0,30);

INSERT INTO EMP VALUES

(7876,'ADAMS','CLERK',7788,to_date('13-7-1987','dd-mm-yyyy'),1100,NULL,20);

INSERT INTO EMP VALUES

(7900,'JAMES','CLERK',7698,to_date('3-12-1981','dd-mm-yyyy'),950,NULL,30);

INSERT INTO EMP VALUES

(7902,'FORD','ANALYST',7566,to_date('3-12-1981','dd-mm-yyyy'),3000,NULL,20);

INSERT INTO EMP VALUES

(7934,'MILLER','CLERK',7782,to_date('23-1-1982','dd-mm-yyyy'),1300,NULL,10);

--==>> 14행이 삽입되었습니다.


--○ 테이블 생성(BONUS)

CREATE TABLE BONUS

( ENAME VARCHAR2(10)

  , JOB VARCHAR2(9)  

  , SAL NUMBER

  , COMM NUMBER

) ;

--==>> Table BONUS이(가) 생성되었습니다.


--○ 테이블 생성(SALGRADE)

DROP TABLE SALGRADE;

CREATE TABLE SALGRADE

      ( GRADE NUMBER,

LOSAL NUMBER,

HISAL NUMBER );

--==>> Table SALGRADE이(가) 생성되었습니다.


--○ 데이터 입력(SALGRADE TABLE)

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);

--==>>5행이 삽입되었습니다.


COMMIT;

--COMMIT명령어 = 메모리상에 올라가진 내용을 HDD에 기록하라!

--==>> 커밋 완료



--ROLLBACK;

--ROLLBACK명령어 = COMMIT과 반대


/*

DB운영에서 가장 중요한 것은 메모리이다

메모리를 얼만큼 아끼는 지가 시간과 비용을 얼만큼 아끼는가 이기 때문이다.


*/







--○ 현재 SCOTT 계정이 소유하고 있는 테이블 조회


SELECT *

FROM TAB;

--==>> TAB는 TABLE의 약자

/*

BONUS    TABLE

DEPT     TABLE

EMP       TABLE

SALGRADE TABLE


SCOTT이 총 4개의 테이블을 가지고 있다!

*/


중요!!!


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

--■■■ SELECT 문의 처리(PARSING) 순서 ■■■--

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

                --필수 암기--

/*

SELECT 컬럼명   -- ⑤   세로방향으로 추려냄

FROM 테이블명   -- ①

WHERE  조건절   -- ②   가로방향으로 추려냄 

GROUP BY   절   -- ③   그룹화

HAVING     절   -- ④   그룹의 조건

ORDER BY   절   -- ⑥   오름차순 / 내림차순


※ 쿼리문 구성할 때 ORDER BY를 사용하지 않는 경우가 있다.

   ORDER BY정렬은 리소스 소모가 굉장히 심해서 

   시스템 부하가 많이 발생하기 때문!

   WHERE 조건절에 만족하는 데이터들만 메모리 상에 올라간다.

   그러므로 WHERE 조건절이 없으면 모든 데이터를 다 스캔하기 때문에 메모리 사용량이 늘어난다.

   

   

   SELECT ENAME

   FROM EMP;

   조건이 하나도 없으므로 TABLE 전체를 스캔하여 메모리 상에 올라간다.

   

   SELECT ENAME, JOB, EMPNO

   FROM EMP

   WHERE ENAME = 'JSW';

   WHERE 조건에 맞는 데이터만 메모리 상에 올라감. 메모리 절약

   

   

*/


--○ BONUS 테이블 조회

SELECT *

FROM BONUS;



--○ 부서정보(DEPT) 테이블 조회

SELECT *

FROM DEPT;


--○ 사원정보(EMP) 테이블 조회

SELECT *

FROM EMP;


--○ 급여 등급(SALGRADE) 테이블 조회

SELECT *

FROM SALGRADE;



--○ 테이블의 구조 확인

DESCRIBE EMP;


/* 실행 결과


이름       널        유형           

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

EMPNO    NOT NULL NUMBER(4)      

        //NOT NULL을 필수 입력사항정도로 이해하자!(비어있으면 안되기 때문!)


ENAME             VARCHAR2(10) 

JOB               VARCHAR2(9)  

MGR               NUMBER(4)    

HIREDATE          DATE         

SAL               NUMBER(7,2)  

COMM              NUMBER(7,2)  

DEPTNO            NUMBER(2) 


*/


/*

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

--■■■ 주요 자료형 ■■■--

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


1. 숫자형  NUMBER

           NUMBER(3)  = -999~999까지 입력 가능

           NUMBER(4,1) = -999.X ~ 999.X 소숫점 첫번째까지 입력가능

                        전체가 4자리이고 소숫점이 1자리

                        

2. 문자형   고정형 크기

            CHAR(10)  = 10바이트 크기인 문자

                        5바이트 만큼의 데이터를 입력해도 10바이트를 차지한다.

            가변형 크기

            VARCHAR2(10)  = 가변형이라고 해서 명시되어 있는 바이트를 넘어갈 수 없다.

                            오버플로우로 짤리는 것이아니라 처음부터 에러가 난다.

                            헤더에 관련 자료의 크기나 정보의 크기가 더 크기때문에 참조할 때 리소스가 더 많이 소모된다.

                            따라서 고정된 길이의 데이터는 CHAR형을 사용한다.

                            

            숫자로 구성된 데이터지만 숫자로 처리하면 안되는 것

            1. 전화번호

            2. 학번

            3. 주민번호

            

            첫시작이 0으로 시작하게 된다면 숫자형이면 앞에 0이 삭제되기 때문!!

            

            

            NCHAR(N)  -   유니코드기반 글자수 (N글자 입력가능)

            NVARCHAR2(N)  - 유니코드기반 글자수 (N글자 입력가능)


3. 날짜형

          DATE  -   




*/


SELECT SYSDATE

FROM DUAL;

--==>>18/01/05


--SESSION  - 연결과 관련되어 있는 정보를 담아두는 공간

ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';


SELECT SYSDATE

FROM DUAL;

--==>>2018-01-05 14:49:06


SELECT 0123

FROM DUAL;

--==>> 123


SELECT '0123'

FROM DUAL;

--==>>0123


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


--○ EMP 테이블에서 부서번호가 20번인 사원들의 정보 중 

--   사원번호, 사원명, 급여, 직종명, 부서번호 조회



SELECT EMPNO

      ,ENAME

      , SAL

      , JOB

      , DEPTNO

FROM EMP

WHERE DEPTNO=20;


-- ※ 각 컬럼에 별칭을 부여할 수 있다.


SELECT EMPNO AS "사원번호", ENAME "사원명", SAL 급여, JOB "직종 명", DEPTNO

FROM EMP

WHERE DEPTNO=20;



--○ EMP 테이블에서 부서번호가 20번과 30번 직원들의 정보 중

--   사원번호, 사원명, 직종명, 급여, 부서번호 항목을 조회한다.


SELECT EMPNO 사원번호, ENAME 사원이름, JOB 직종명, SAL 급여, DEPTNO 부서번호

FROM EMP

WHERE DEPTNO=20 OR DEPTNO=30

ORDER BY SAL ASC;


--위와 아래는 같은 구문


SELECT EMPNO 사원번호, ENAME 사원이름, JOB 직종명, SAL 급여, DEPTNO 부서번호

FROM EMP

WHERE DEPTNO IN(20,30);



--○ || 문자열 결합 연산자


SELECT 'A'||'B'

FROM DUAL;


--○ EMP 테이블에서 직종이 CLERK인 사원들의 정보를 모두 조회한다


SELECT *

FROM EMP

WHERE JOB='CLERK';


-- 오라클에서 입력된 데이터(값) 만큼은 반드시 대소문자 구분을 해야한다.


--○ 테이블 복사

--> 내부적으로 대상 테이블 안에 들어있는 데이터 내용만 복사하는 과정


CREATE TABLE TBL_EMP

AS  -- 저거저거~~ 저거로 만들어달라

SELECT *

FROM EMP;


SELECT *

FROM TBL_EMP;



--○ 이미 만들어진 테이블에 컬럼 추가

-- TBL_EMP 테이블에 주민번호 정보를 담을 수 있는 컬럼(SSN) 추가


ALTER TABLE TBL_EMP

ADD SSN CHAR(13);

--==>> Table TBL_EMP이(가) 변경되었습니다.


/*

INSERT / UPDATE / DELETE 와 같은 DML구문을 작성한 이후에는

선택적으로 COMMIT이나 ROLLBACK을 해야한다.


다른 구문들은 자동적으로 COMMIT을 실행해준다!


한쪽은 오토 COMMIT을 해주는 사이에 잘못 적힌 데이터를 수정하지 않았을 경우

잘못된 데이터가 메모리에 올라 갈 수 있다 주의 주의 

*/


-- 컬럼이 추가된 테이블 구조 확인

DESC TBL_EMP;


/*

이름       널 유형           

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

EMPNO      NUMBER(4)    

ENAME      VARCHAR2(10) 

JOB        VARCHAR2(9)  

MGR        NUMBER(4)    

HIREDATE   DATE         

SAL        NUMBER(7,2)  

COMM       NUMBER(7,2)  

DEPTNO     NUMBER(2)    

SSN        CHAR(13) 

*/



SELECT *

FROM TBL_EMP;

/*

SSN이 NULL로 되어있음

1. 컬럼의 구성되어 있는 순서는 중요하지 않다 아니 의미가 없다.

2. 데이터를 채우려면 UPDATE해야함

   레코드 한개가 하나의 데이터인데 SSN에 데이터를 삽입하려면

   UPDATE를 사용해야함

*/


ALTER TABLE TBL_EMP DROP COLUMN SSN;


SELECT *

FROM TBL_EMP;


SELECT *

FROM EMP;


ALTER TABLE TBL_EMP

ADD SSN CHAR(13);


/*

DELETE 실수를 하지 않는 방법


SELECT *

FROM TBL_EMP

WHERE EMPNO=7369;


처음에 삭제해야 하는 것을 확인!!


DELETE

FROM TBL_EMP

WHERE EMPNO=7369;


COMMIT;


SELECT *을 DELETE로 바꾼후 실행!

*/


-- TBL_EMP 테이블 삭제


DROP TABLE TBL_EMP;

--오라클 휴지통에 들어가 있음


SELECT *

FROM TAB;

--이상한 글자가 있음 DROP 한 것

-- BIN$Aa411Q6JRXexdxVM7/zvrw==$0

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


--○ NULL의 처리


SELECT 2, 1+2, 3-1

FROM DUAL;


--==>>2 3 2




SELECT 2+NULL, 2-NULL, 2*NULL, 2/NULL

FROM DUAL;

--==>>NULL NULL NULL NULL


--※ NULL은 현실에 존재하는 특정한 값을 의미하는 것이 아니라

--   아무것도 들어있지 않은 상태를 의미하는 값이므로 

--   NULL을 대상으로 연산을 수행할 경우 또는 특정 연산 과정에 NULL이 포함될 경우

--   결과는 무조건 NULL이다.



--○  다시 EMP 테이블을 복사하여 TBL_EMP테이블을 생성


CREATE TABLE TBL_EMP

AS

SELECT *

FROM EMP;

--==>>Table TBL_EMP이(가) 생성되었습니다.



--○ TBL_EMP 테이블에서 커미션(COMM) → 수당이 NULL인 사원들의

--   사원명, 직종명, 급여, 커미션을 조회한다.


SELECT ENAME 사원명, JOB 직종명, SAL 급여, COMM 커미션

FROM TBL_EMP

WHERE COMM IS NULL;


--※ NULL은 값으로 존재하는 것이 아니기 때문에 값으로 비교할 수 없다.

--   =, >=, <=, !=, <>, >, < 와 같은 연산자를 사용할 수 없다.  !=와 <> ^= 모두 같지 않다는 의미


--○ TBL_EMP 테이블에서 20번 부서에 근무하지 않는 사원들의 정보를 

--   사원번호, 사원명, 부서번호로 조회한다.


SELECT EMPNO 사원번호, ENAME 사원명, DEPTNO 부서번호 

FROM TBL_EMP

WHERE DEPTNO!=20;


SELECT EMPNO 사원번호, ENAME 사원명, DEPTNO 부서번호

FROM TBL_EMP

WHERE NOT DEPTNO=20;



--TBL_EMP 테이블에서 COMM(커미션)이 NULL이 아닌 것을 조회


SELECT *

FROM TBL_EMP

WHERE COMM IS NOT NULL;



SELECT *

FROM TBL_EMP

WHERE NOT COMM IS NULL;



--○ TBL_EMP 테이블에서 모든 사원들의 

--   사원번호, 사원명, 급여, 커미션, 연봉 정보를 조회한다.

--   단, 급여(SAL)는 매월 지급한다.

--   수당(COMM)은 1회/년 지급한다.


ALTER TABLE TBL_EMP

ADD MONEY NUMBER(10);


ALTER TABLE TBL_EMP DROP COLUMN MONEY;


SELECT EMPNO 사원번호, ENAME 사원명, SAL 급여, COMM 커미션, (SAL*12)+(NVL(COMM,0)) 연봉

FROM TBL_EMP;



반응형

'Database' 카테고리의 다른 글

오라클 다중 WHERE조건  (0) 2018.06.25
무결성 (Integrity)  (0) 2018.01.12
JOIN (조인)  (0) 2018.01.12
오라클 SQL Developer 2018.01.09  (0) 2018.01.09
데이터베이스와 DBMS 개요  (0) 2018.01.09
반응형

■■■ 데이터베이스 DBMS 개념 ■■■


DBMS전에는 파일시스템으로 데이터를 관리했다.


데이터 - 데이터는 정보보다 작은 단위 즉, 데이터를 여러개 모으면 정보가 된다.


베이스 - 데이터를 모아두는 기반/장소/장치


데이터란 현실 세계에서 관찰이나 측정을 통해 수집된

사실(fact)이나 값(value)을 말한다.


정보란 데이터의 유효한 해석이나 데이터 상호간의 관계를

의사 결정에 도움이 되도록 가공한 것이다.


데이터베이스란 여러 응용시스템이 공유할 수 있도록

통합, 저장된 운영 데이터의 집합이다.



■■■ DBMS ■■■


○ DBMS 란?

   파일 관리 시스템의 단점을 개선하여 데이터를 통합적으로 관리하는 소프트웨어로

   컴퓨터에 수록한 수많은 자료들을 쉽고 빠르게 추가 / 삭제 / 검색할 수 있는 시스템이다.


   흔히 DBMS라고 하면 어떤 하드웨어적인 서버를 생각하는 경우가 많은데

   데이터베이스 관리 시스템은 시스템이나 장비가 아닌 논리적인 소프트웨어이다.


   즉, 사용자들은 응용프로그램을 이용하여 SQL명령을 DBMS에 전달하며

   DBMS는 이러한 사용자들의 명령을 받아 해석하고 이를 컴퓨터에서 처리할 수 있는 형태로 변환하여 실행하며

   이와 관련된 모든 프로세서를 관리하는 논리적인 소프트웨어인 것이다.


데이터베이스 관리 시스템(DBMS)

DBMS : DataBase Management System이란

모든 응용 프로그램들이 데이터베이스를 공유할 수 있도록 관리해주고,

데이터베이스를 유지하기 위한 일련의 소프트웨어 시스템이다.



반응형

'Database' 카테고리의 다른 글

오라클 다중 WHERE조건  (0) 2018.06.25
무결성 (Integrity)  (0) 2018.01.12
JOIN (조인)  (0) 2018.01.12
오라클 SQL Developer 2018.01.09  (0) 2018.01.09
오라클 SQL Developer 2018.01.05  (0) 2018.01.09

+ Recent posts