본문 바로가기
  • 문과생의 백엔드 개발자 성장기
|Playdata_study/SQL.Oracle

210525 _DB3 (SQL) / 집합(SET)연산, 서브쿼리

by 케리's 2021. 5. 25.

✨ 집합(SET) 연산자를 이해하고 기술 할 수 있다.
✨ SUBQUERY를 기술할 수 있다.

 

집합(SET)연산

  SET 연산자는 두 개 이상의 질의 결과를 하나의 결과로 통합하며,

  SET 연산자를 포함하는 질의를 복합 질의라고한다. → 여기서 질의는 쿼리를 말함.

 

UNION 

 

  두 질의 중 어느 것 하나에 의해서라도 선택된 모든 구분 (DISTINCT) 행을 결과로 한다.
  양쪽 질의에 의해서 선택된 행을 모두 포함한다.

  중복 값은 한번만 리턴하며,  첫번째 컬럼을 기준으로 ASC 정렬한다.

 

UNION ALL 

 

  중복 행을 포함하여 두 질의 중 어느 것 하나에 의해서 선택된 모든 행을 결과로한다.
  DISTINCT 와 같이 사용 불가.

 

INTERSECT

 

  두 질의에 공통으로 선택된 모든 구분(DISTINCT) 행을 결과로 한다.
  첫 번째 선택 문장에서 두번째 선택 문장과 일치하는 최소한 하나의 행을 리턴한다.

 

MINUS

 

  첫 째 SELECT문에 선택되고, 둘 째 SELECT문에서 선택되지 않은 모든 구분(DISTINCT)행을 결과로한다.
  (두번째 선택 문장에서는 선택되지 않는 첫번째 선택 문장에 의해 선택된 모든 유일한 행이다)
 

👉 모든 SET 연산자는 같은 우선순위를 가진다.

 

   SQL 문장이 여러 개 SET 연산자를 포함한다면 데이터 베이스는 명시적으로
   다른 순서를 명시하는 괄호가 없을 경우 왼쪽( )에서 오른쪽 (아래)로 실행을 한다.
   사용하는 질의의 평가 순서를 명시적으로 표현하기 위해서는 괄호를 사용한다.

[형식]


SELECT : FROM WHERE GROUP BY HAVING
            SET 연산자
SELECT FROM WHERE GROUP BY HAVING

ORDER BY

 

 

□ UNION

 

  컬럼의 개수가 두 개의 SELECT 문장에 일치 하여야 한다.
  컬럼의 이름은 같지 않아도 된다.
  중복 값은 하나만 리턴 된다.
  WHERE 절에서 UNION을 사용하는 질의를 SELECT 목록에 있는 것과 똑같은 수와 데이터 타입의 열을 가져야한다.

 

 

Q1) 데이터 생성을 해보자.

 

CREATE TABLE EMP_HISTORY(NAME, TITLE, DEPTID)
AS
SELECT ENAME, JOB, DEPTNO
FROM EMP;

DESC EMP_HISTORY

SQL>   CREATE TABLE EMP_HISTORY(NAME, TITLE, DEPTID)
  2    AS
  3    SELECT ENAME, JOB, DEPTNO
  4    FROM EMP;

Table created.

SQL> DESC EMP_HISTORY
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 NAME                                               VARCHAR2(10)
 TITLE                                              VARCHAR2(9)
 DEPTID                                             NUMBER(2)

SQL>

 

 

Q2) EMP 테이블과 EMP_HISTORY 테이블의 내용을 UNION 연산을 구현하자.


SELECT ENAME, JOB, DEPTNO
FROM EMP
UNION
SELECT NAME, TITLE, DEPTID
FROM EMP_HISTORY;

 

SQL> SELECT ENAME, JOB, DEPTNO
  2  FROM EMP
  3  UNION
  4  SELECT NAME, TITLE, DEPTID
  5  FROM EMP_HISTORY;

ENAME                JOB                    DEPTNO
-------------------- ------------------ ----------
ALLEN                SALESMAN                   30
BLAKE                MANAGER                    30
CLARK                MANAGER                    10
FORD                 ANALYST                    20
JAMES                CLERK                      30
JONES                MANAGER                    20
KING                 PRESIDENT                  10
MARTIN               SALESMAN                   30
MILLER               CLERK                      10
SMITH                CLERK                      20
TURNER               SALESMAN                   30

ENAME                JOB                    DEPTNO
-------------------- ------------------ ----------
WARD                 SALESMAN                   30

12 rows selected.

 

□ UNION ALL

 

Q3) EMP 테이블과 EMP_HISTORY 테이블의 내용을 UNION ALL연산을 구현하자.


SELECT ENAME, JOB, DEPTNO
FROM EMP
UNION ALL
SELECT NAME, TITLE, DEPTID
FROM EMP_HISTORY;

 

SQL> SELECT ENAME, JOB, DEPTNO
  2    FROM EMP
  3    UNION ALL
  4    SELECT NAME, TITLE, DEPTID
  5    FROM EMP_HISTORY;

ENAME                JOB                    DEPTNO
-------------------- ------------------ ----------
SMITH                CLERK                      20
ALLEN                SALESMAN                   30
WARD                 SALESMAN                   30
JONES                MANAGER                    20
MARTIN               SALESMAN                   30
BLAKE                MANAGER                    30
CLARK                MANAGER                    10
KING                 PRESIDENT                  10
TURNER               SALESMAN                   30
JAMES                CLERK                      30
FORD                 ANALYST                    20

ENAME                JOB                    DEPTNO
-------------------- ------------------ ----------
MILLER               CLERK                      10
SMITH                CLERK                      20
ALLEN                SALESMAN                   30
WARD                 SALESMAN                   30
JONES                MANAGER                    20
MARTIN               SALESMAN                   30
BLAKE                MANAGER                    30
CLARK                MANAGER                    10
KING                 PRESIDENT                  10
TURNER               SALESMAN                   30
JAMES                CLERK                      30

ENAME                JOB                    DEPTNO
-------------------- ------------------ ----------
FORD                 ANALYST                    20
MILLER               CLERK                      10

24 rows selected.

SQL>

 

□ INTERSECT

 

Q4) TEST_EMP, EMP 이용해서 INTERSECT 해보자. #교집합

 

SELECT ENAME, JOB, DEPTNO
FROM TEST_EMP
INTERSECT
SELECT ENAME, JOB, DEPTNO
FROM EMP;

 

SQL> SELECT ENAME, JOB, DEPTNO
  2    FROM EMP
  3    INTERSECT
  4    SELECT ENAME, JOB, DEPTNO
  5    FROM TEST_EMP;

ENAME                JOB                DEPTNO
-------------------- ------------------ ------
ALLEN                SALESMAN               30
BLAKE                MANAGER                30
CLARK                MANAGER                10
FORD                 ANALYST                20
JAMES                CLERK                  30
JONES                MANAGER                20
KING                 PRESIDENT              10
MARTIN               SALESMAN               30
MILLER               CLERK                  10
SMITH                CLERK                  20
TURNER               SALESMAN               30

ENAME                JOB                DEPTNO
-------------------- ------------------ ------
WARD                 SALESMAN               30

12 rows selected.

 

# 위치 바꿔도 동일


SELECT ENAME, JOB, DEPTNO
FROM EMP
INTERSECT
SELECT ENAME, JOB, DEPTNO
FROM TEST_EMP;

 

□ MINUS

 

Q5) EMP 테이블과 EMP_HISTORY 테이블의 내용을 MINUS연산을 구현하자. #차집합

SELECT ENAME, JOB, DEPTNO
FROM TEST_EMP
MINUS
SELECT NAME, TITLE, DEPTID
FROM EMP;

 

SQL> SELECT ENAME, JOB, DEPTNO
  2    FROM TEST_EMP
  3    MINUS
  4    SELECT ENAME, JOB, DEPTNO
  5    FROM EMP;

ENAME                JOB                DEPTNO
-------------------- ------------------ ------
111                                         30
222                                         30
333                                         20
444                                         20
777

 

Q6) EMP, DEPT에서 부서번호, 부서이름, 입사일을 UNION 연산자를 이용해서 출력해보자.


SELECT DEPTNO,TO_CHAR(NULL),HIREDATE
FROM EMP
UNION
SELECT DEPTNO, DNAME, TO_DATE(NULL)
FROM DEPT
ORDER BY 1;

 

SQL> SELECT DEPTNO, TO_CHAR(NULL), HIREDATE
  2  FROM EMP
  3  UNION
  4  SELECT DEPTNO, DNAME, TO_DATE(NULL)
  5  FROM DEPT
  6  ORDER BY 1;

    DEPTNO TO_CHAR(NULL)                HIREDATE
---------- ---------------------------- --------
        10 ACCOUNTING
        10                              81/06/09
        10                              81/11/17
        10                              82/01/23
        20 RESEARCH
        20                              80/12/17
        20                              81/04/02
        20                              81/12/03
        30 SALES
        30                              81/02/20
        30                              81/02/22

    DEPTNO TO_CHAR(NULL)                HIREDATE
---------- ---------------------------- --------
        30                              81/05/01
        30                              81/09/08
        30                              81/09/28
        30                              81/12/03
        40 OPERATIONS

16 rows selected.

SQL>

 

 


SUBQUERY

 

 SINGLE ROW SUBQUERY, MULTI ROW SUBQUERY
 MULTI COLUMN SUBQUERY
 SCALAR SUBQUERY

 CORRELATED SUBQUERY
 WITH 절과 SUBQUERY

 

※ SCALAR ? 프로그램에서 자료형 의미한다. 단일 값을 의미한다. 정수, 문자, 문자열 등

 


Q1)  'JONES' 보다 더 많은 월급을 받는 사원의 이름과 월급을 출력해보자.

 

(1) 먼저 이름이 'JONES' 인 사원의 월급을 구한다.


SELECT SAL
FROM EMP
WHERE ENAME = 'JONES';

 

SQL> SELECT SAL
  2  FROM EMP
  3  WHERE ENAME = 'JONES';

       SAL
----------
      2975

SQL>

 

(2) 구한 월급 이상을 대상으로 사원의 이름과 직업을 리턴한다.


SELECT ENAME, SAL
FROM EMP
WHERE SAL > 2975;

 

SQL> SELECT ENAME, SAL
  2  FROM EMP
  3  WHERE SAL > 2975;

ENAME                       SAL
-------------------- ----------
KING                       5000
FORD                       3000

 

 

✔ 서브쿼리

  : 괄호로 묶여저 있는것 먼저 실행 한다.

   OUTER QUERY / INNER QUERY

 

(3) 결과

 

SELECT ENAME, SAL
FROM EMP
WHERE SAL > (SELECT SAL
                    FROM EMP
                    WHERE ENAME = 'JONES');

SQL> SELECT ENAME, SAL
  2  FROM EMP
  3  WHERE SAL > (SELECT SAL
  4                      FROM EMP
  5                      WHERE ENAME = 'JONES');

ENAME                       SAL
-------------------- ----------
KING                       5000
FORD                       3000

SQL>

 


[형식]


SELECT ---------->  기본질의
FROM

WHERE (SELECT
            FROM
            WHERE) ------> 서브쿼리

 


  1. 서브쿼리는 일반적으로 기본질의 실행 전에 한번 실행된다.
  2. 서브쿼리의 결과는 기본질의(외부질의, 주 쿼리, 메인쿼리리) 사용된다.
  3. 서브쿼리는 ( ) 로 묶여있다.
  4. 비교조건의 오른쪽에 서브쿼리를 명시한다.
  5. 일반적인 서브쿼리(TOP-N 분석 제외) 에서는 ORDER BY 절을 사용하지 않는다.
  6. 단일행 연산자 ( >, <, >=, <=, ==, !=), 복수행 연산자 (IN, ANY, ALL)을 사용한다.
  7. SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY, UPDATE, INSERT, DELETE문 에서 올 수 있다.

 


Q2) 7566 사원보다 더 많은 월급을 받는 사원의 이름을 출력해보자.

SELECT ENAME, SAL
FROM EMP
WHERE SAL > (SELECT SAL
                    FROM EMP
                    WHERE EMPNO = 7566);

 

SQL> SELECT ENAME, SAL
  2  FROM EMP
  3  WHERE SAL > (SELECT SAL
  4              FROM EMP
  5              WHERE EMPNO = 7566);

ENAME                       SAL
-------------------- ----------
KING                       5000
FORD                       3000

SQL>



Q3) 급여의 평균보다 적은 사원의 사원번호, 이름, 급여 부서번호 출력하자

 

SELECT EMPNO, ENAME, JOB, SAL, DEPTNO
FROM EMP
WHERE SAL < (SELECT AVG(SAL)
                    FROM EMP);

 

SQL> SELECT EMPNO, ENAME, JOB, SAL, DEPTNO
  2  FROM EMP
  3  WHERE SAL < (SELECT AVG(SAL)
  4              FROM EMP);

     EMPNO ENAME                JOB                       SAL     DEPTNO
---------- -------------------- ------------------ ---------- ----------
      7369 SMITH                CLERK                     800         20
      7499 ALLEN                SALESMAN                 1600         30
      7521 WARD                 SALESMAN                 1250         30
      7654 MARTIN               SALESMAN                 1250         30
      7844 TURNER               SALESMAN                 1500         30
      7900 JAMES                CLERK                     950         30
      7934 MILLER               CLERK                    1300         10

7 rows selected.

 


Q4) 사원의 번호가 7521인 사원의 직업과 같고

     급여가 7934 사원보다 많은 사원의 사원번호, 이름, 직업, 입사일자 급여를 조회하자.

 

SELECT EMPNO, ENAME, JOB, HIREDATE, SAL
FROM EMP
WHERE SAL > (SELECT SAL
                    FROM EMP
                    WHERE EMPNO = 7934)
AND
JOB = (SELECT JOB
          FROM EMP
          WHERE EMPNO = 7521);

 

SQL> SELECT EMPNO, ENAME, JOB, HIREDATE, SAL
  2  FROM EMP
  3  WHERE SAL > (SELECT SAL
  4               FROM EMP
  5               WHERE EMPNO = 7934)
  6  AND
  7  JOB = (SELECT JOB
  8         FROM EMP
  9         WHERE EMPNO = 7521);

     EMPNO ENAME                JOB                HIREDATE        SAL
---------- -------------------- ------------------ -------- ----------
      7499 ALLEN                SALESMAN           81/02/20       1600
      7844 TURNER               SALESMAN           81/09/08       1500

SQL>

 



Q5) 사원 테이블에서 사원의 급여가 20번 부서의 최소 급여보다 많은 부서 리턴

 


SELECT DEPTNO, MIN(SAL)
FROM EMP
GROUP BY DEPTNO
HAVING MIN(SAL) > (SELECT MIN(SAL)
FROM EMP
WHERE DEPTNO = 20);

 

SQL> SELECT DEPTNO, MIN(SAL)
  2  FROM EMP
  3  GROUP BY DEPTNO
  4  HAVING MIN(SAL) = (SELECT MIN(SAL)
  5                     FROM EMP
  6                     WHERE DEPTNO = 20);

    DEPTNO   MIN(SAL)
---------- ----------
        20        800

 


Q6) 사원 테이블에서 직업중에서 가장 작은 평균 급여를 받는 직업을 조회하자.

 

SELECT JOB, AVG(SAL)
FROM EMP
GROUP BY JOB
HAVING AVG(SAL) = (SELECT MIN(AVG(SAL))
                            FROM EMP
                            GROUP BY JOB);

 

SQL> SELECT JOB, AVG(SAL)
  2  FROM EMP
  3  GROUP BY JOB
  4  HAVING AVG(SAL) = (SELECT MIN(AVG(SAL))
  5  			FROM EMP
  6  			GROUP BY JOB);

JOB                  AVG(SAL)
------------------ ----------
CLERK              1016.66667

SQL>


Q7) 직업이 SALESMAN 인 최소 한명 이상의 사원보다 급여를 많이받는 사원의 이름, 급여, 직업을 출력하자.

SELECT ENAME, SAL, JOB
FROM EMP
WHERE SAL > (SELECT SAL
                    FROM EMP
                    WHERE JOB = 'SALESMAN');

 

# 멀티 ROW 연산자, SALESMAN 값이 많음
ORA-01427: single-row subquery returns more than one row

 

SQL> SELECT ENAME, SAL, JOB
  2  FROM EMP
  3  WHERE SAL > (SELECT SAL
  4             FROM EMP
  5             WHERE JOB = 'SALESMAN');
WHERE SAL > (SELECT SAL
             *
ERROR at line 3:
ORA-01427: single-row subquery returns more than one row

 


✔ 다중행 서브쿼리

 

 IN : 목록에 있는 임의의 값과 동일하다. DATA OR , DATA OR, ,
 ANY : 값을 반환하는 각가의 값과 개별 비교한다.

 

  < ANY  :  최대 값보다 적음
  > ANY  :  최소 값 보다 크다
  = ANY  :  IN 연산자와 동일

ALL : 서브쿼리에 의해 반환되는 모든값과 비교한다.


  < ALL  : 최소 값보다 작음
  > ALL  : 최대 값 보다 클때

 

NOT : IN, ANY, ALL 연산자와 함께 사용된다.

 

 

 

# Q7과 동일적용 해보자.


SELECT ENAME, SAL, JOB
FROM EMP
WHERE SAL >ANY (SELECT SAL
                         FROM EMP
                         WHERE JOB = 'SALESMAN');

 

SQL> SELECT ENAME, SAL, JOB
  2  FROM EMP
  3  WHERE SAL > ANY (SELECT SAL
  4             FROM EMP
  5             WHERE JOB = 'SALESMAN');

ENAME                       SAL JOB
-------------------- ---------- ------------------
KING                       5000 PRESIDENT
FORD                       3000 ANALYST
JONES                      2975 MANAGER
BLAKE                      2850 MANAGER
CLARK                      2450 MANAGER
ALLEN                      1600 SALESMAN
TURNER                     1500 SALESMAN
MILLER                     1300 CLERK

8 rows selected.

 


SELECT ENAME, SAL, JOB
FROM EMP
WHERE JOB!= 'SALESMAN'
AND SAL > ANY (SELECT SAL
                       FROM EMP
                       WHERE JOB = 'SALESMAN');

 

SQL> SELECT ENAME, SAL, JOB
  2  FROM EMP
  3  WHERE JOB! = 'SALESMAN'
  4  AND SAL > ANY (SELECT SAL
  5                 FROM EMP
  6                 WHERE JOB = 'SALESMAN');

ENAME                       SAL JOB
-------------------- ---------- ------------------
KING                       5000 PRESIDENT
FORD                       3000 ANALYST
JONES                      2975 MANAGER
BLAKE                      2850 MANAGER
CLARK                      2450 MANAGER
MILLER                     1300 CLERK

6 rows selected.

SQL>

 


Q8) 직업이 SALESMAN 인 모든 사원보다 급여를 많이 받는 사원의 이름, 봉급, 직업, 입사일, 부서번호 출력

 


SELECT ENAME, SAL, JOB, HIREDATE, DEPTNO
FROM EMP
WHERE SAL > ALL (SELECT SAL
                   FROM EMP
                   WHERE JOB = 'SALESMAN');

 

SQL> SELECT ENAME, SAL, JOB, HIREDATE, DEPTNO
  2  FROM EMP
  3  WHERE SAL > ALL(SELECT SAL
  4             FROM EMP
  5             WHERE JOB = 'SALESMAN');

ENAME                       SAL JOB                HIREDATE     DEPTNO
-------------------- ---------- ------------------ -------- ----------
CLARK                      2450 MANAGER            81/06/09         10
BLAKE                      2850 MANAGER            81/05/01         30
JONES                      2975 MANAGER            81/04/02         20
FORD                       3000 ANALYST            81/12/03         20
KING                       5000 PRESIDENT          81/11/17         10

SQL>

 


SELECT ENAME, SAL, JOB, HIREDATE, DEPTNO
FROM EMP
WHERE JOB!= 'SALESMAN'
AND SAL > ALL (SELECT SAL
                      FROM EMP
                      WHERE JOB = 'SALESMAN');

 

SQL> SELECT ENAME, SAL, JOB, HIREDATE, DEPTNO
  2  FROM EMP
  3  WHERE JOB!= 'SALESMAN'
  4  AND SAL > ALL (SELECT SAL
  5               FROM EMP
  6               WHERE JOB = 'SALESMAN');

ENAME                       SAL JOB                HIREDATE     DEPTNO
-------------------- ---------- ------------------ -------- ----------
CLARK                      2450 MANAGER            81/06/09         10
BLAKE                      2850 MANAGER            81/05/01         30
JONES                      2975 MANAGER            81/04/02         20
FORD                       3000 ANALYST            81/12/03         20
KING                       5000 PRESIDENT          81/11/17         10




□ MULTI COLUMN SUBQUERY (다중열서브쿼리)

   : 서브쿼리의 결과 값이 두 개 이상의 컬럼을 반환하는 서브쿼리로 혼합 WHERE 를 작성한다.
     (중복된 WHERE 조건을 하나의 WHERE 절로 결합시킨다.)

 


Q9) FORD, BLAKE 와 관리자 및 부서가 같은 사원의 정보를 출력해보자.

     - NON-PAIRWISE 비교 


SELECT ENAME, MGR, DEPTNO
FROM EMP
WHERE MGR IN (SELECT MGR
                      FROM EMP
                      WHERE ENAME IN ('FORD','BLAKE'))
AND 
      DEPTNO IN (SELECT DEPTNO
                      FROM EMP
                      WHERE ENAME IN ('FORD','BLAKE'))
AND
      ENAME NOT IN ('FORD','BLAKE');

 

SQL> SELECT ENAME, MGR, DEPTNO
  2  FROM EMP
  3  WHERE MGR IN (SELECT MGR
  4                        FROM EMP
  5                        WHERE ENAME IN ('FORD','BLAKE'))
  6  AND
  7        DEPTNO IN (SELECT DEPTNO
  8                        FROM EMP
  9                        WHERE ENAME IN ('FORD','BLAKE'))
 10  AND
 11        ENAME NOT IN ('FORD','BLAKE');

ENAME                  MGR DEPTNO
-------------------- ----- ------
JONES                 7839     20





Q10) FORD, BLAKE 와 관리자 및 부서가 같은 사원의 정보를 출력해보자.

      - PAIRWISE 비교 

SELECT ENAME, MGR, DEPTNO
FROM EMP
WHERE (MGR, DEPTNO) IN (SELECT MGR, DEPTNO
                                    FROM EMP
                                    WHERE ENAME IN ('FORD', 'BLAKE'))
AND
      ENAME NOT IN ('FORD','BLAKE');

 

SQL> SELECT ENAME, MGR, DEPTNO
  2  FROM EMP
  3  WHERE (MGR,DEPTNO) IN (SELECT MGR, DEPTNO
  4                      FROM EMP
  5                      WHERE ENAME IN ('FORD','BLAKE'))
  6     AND
  7     ENAME NOT IN ('FORD','BLAKE');

no rows selected

 


=============================
SELECT ENAME, MGR, DEPTNO
FROM EMP
WHERE MGR IN (FORD_EMPNO, BLAKE_EMPNO) AND DEPTNO IN (30,20);

SELECT ENAME, MGR, DEPTNO
FROM EMP
WHERE (MGR, DEPTNO) IN ((FORD_EMPNO,30), (BLAKE_EMPNO,20));
= WHERE (MGR, DEPTNO) IN ((7839,30), (7566,20));

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

 

□ CORRELATED SUBQUERY

 

SELECT
FROM TABLE1 MAIN
WHERE COLUMN1 OPERATOR (SELECT
                                         FROM TABLE2
                                         WHERE EXPR1 = MAIN.EXPR2);

  - 메인 쿼리의 한 ROW에 대해서 서브쿼리가 한번 씩 실행된다.
  - 테이블에서 행을 먼저 읽어서 각 행의 값을 관련된 데이터와 비교한다.
  - 기본 질의에서 각 후보행에 대해 서브쿼리가 다른 결과를 반환해야 하는 경우 사용된다.
  - 서브 쿼리에서 메인 쿼리의 컬럼명을 사용할 수 있으나, 메인쿼리에서는 서브쿼리의 컬럼명을 사용할 수 없다.

실행


후보행을 메인쿼리에서 가저온다 → 후보행의 값을 사용해서 서브쿼리를 실행한다.
→ 서브쿼리의 결과 값을 사용하여 후보행의 조건을 확인한다.→ 후보행이 남지 않을 떄 까지 반복한다.

 

 

Q11) 


사원의 속한 부서의 평균 급여보다 많은 급여를 받는 사원의 이름, 급여, 부서번호, 입사일 직업을 출력하자.
(서브쿼리에서 메인 쿼리의 컬럼명을 사용할 수 있으나)
   E. DEPTNO 는 메인쿼리의 EMP E로 지정된 테이블의 부서번호 값을 참조한다.

SELECT ENAME, SAL, DEPTNO, HIREDATE, JOB
FROM EMP E
WHERE SAL > (SELECT AVG(SAL)
FROM EMP
WHERE DEPTNO = E.DEPTNO);

 

SQL> SELECT ENAME, SAL, DEPTNO, HIREDATE, JOB
  2  FROM EMP E
  3  WHERE SAL > (SELECT AVG(SAL)
  4             FROM EMP
  5             WHERE DEPTNO = E.DEPTNO);

ENAME                  SAL DEPTNO HIREDATE JOB
-------------------- ----- ------ -------- ------------------
ALLEN                 1600     30 81/02/20 SALESMAN
JONES                 2975     20 81/04/02 MANAGER
BLAKE                 2850     30 81/05/01 MANAGER
KING                  5000     10 81/11/17 PRESIDENT
FORD                  3000     20 81/12/03 ANALYST

SQL>

 

□ 인라인 뷰 (INLINE VIEW) 

   :  원하는 테이블이 많을 경우 간추려서 사용할려고 이용한다.  (속도빠르게)
      FROM 절에 오는 서브쿼리

 

SELECT
FROM (SELECT ....)
WHERE 조건식 ;

 


Q12) 

 

사원의 속한 부서의 평균 급여보다 많은 급여를 받는 사원의 이름, 급여, 부서번호, 입사일 직업을 출력하자.

 

SELECT E.ENAME, E.SAL, E.DEPTNO, E.HIREDATE, D.AVGSAL
FROM EMP E, (SELECT DEPTNO, AVG(SAL) AVGSAL
                   FROM EMP
                   GROUP BY DEPTNO) D
WHERE E.DEPTNO = D.DEPTNO
AND E.SAL > D.AVGSAL;

 

SQL> SELECT E.ENAME, E.SAL, E.DEPTNO, E.HIREDATE, D.AVGSAL
  2  FROM EMP E, (SELECT DEPTNO, AVG(SAL) AVGSAL
  3             FROM EMP
  4             GROUP BY DEPTNO) D
  5  WHERE E.DEPTNO = D.DEPTNO
  6  AND E.SAL > D.AVGSAL;

ENAME                  SAL DEPTNO HIREDATE AVGSAL
-------------------- ----- ------ -------- ------
ALLEN                 1600     30 81/02/20   1567
JONES                 2975     20 81/04/02   2258
BLAKE                 2850     30 81/05/01   1567
KING                  5000     10 81/11/17   2917
FORD                  3000     20 81/12/03   2258

SQL>

 


□ TOP-N QUERY

 


Q13) 사원테이블에서 사원 중 급여를 많이받는 상위 3명의 이름, 급여를 조회해보자.

 

SELECT ROWNUM, ENAME, SAL
FROM EMP
WHERE ROWNUM <4
ORDER BY SAL DESC;

 

SQL> SELECT ROWNUM, ENAME, SAL
  2  FROM EMP
  3  WHERE ROWNUM < 4
  4  ORDER BY SAL DESC;

ROWNUM ENAME                  SAL
------ -------------------- -----
     2 ALLEN                 1600
     3 WARD                  1250
     1 SMITH                  800

SQL>


SELECT ROWNUM, ENAME, SAL
FROM (SELECT*
          FROM EMP
          ORDER BY SAL DESC)
WHERE ROWNUM <4;

SQL> SELECT ROWNUM, ENAME, SAL
  2  FROM (SELECT*
  3            FROM EMP
  4            ORDER BY SAL DESC)
  5  WHERE ROWNUM <4;

ROWNUM ENAME                  SAL
------ -------------------- -----
     1 KING                  5000
     2 FORD                  3000
     3 JONES                 2975

SQL>


Q14) 4등에서 7등까지 출력해보자.

 

SELECT ROWNUM, ENAME, SAL
FROM (SELECT *
          FROM EMP
          ORDER BY SAL DESC)
WHERE ROWNUM < 8

MINUS
SELECT ROWNUM, ENAME, SAL
FROM (SELECT *
          FROM EMP
           ORDER BY SAL DESC)
WHERE ROWNUM <5;

  -> 다시해볼것! 

 


□ 스칼라 서브 쿼리

 

 - 하나의 행 에서 하나의 열 값만 반환 하는 서브쿼리를 스칼라 서브쿼리 라고한다.
 - SELECT, INSERT 문의 VALUES목록, DECODE CASE 의 조건 및 표현식 부분, GROUP BY 를 제외한

   SELECT 의 모든 절, UPDATE문의 SET절 및 WHERE 절에서 연산자 목록
 - 서브 쿼리가 0개행을 반환하면 스칼라 서브쿼리의 값은 NULL이다.
 - 서브쿼리가 2개 이상일 때는 행을 반환하는 오류가 발생한다.

Q15) EMP 테이블에서 사원번호, 이름, 봉급, 부서번호, 본인 부서의 평균 급여를 조회하자.


SELECT EMPNO, ENAME, SAL, DEPTNO,
(SELECT AVG(SAL) FROM EMP WHERE DEPTNO = E.DEPTNO) AS ASAL
FROM EMP E;

 

SQL> SELECT EMPNO, ENAME, SAL, DEPTNO,
  2  (SELECT AVG(SAL) FROM EMP WHERE DEPTNO = E.DEPTNO) AS ASAL
  3  FROM EMP E;

EMPNO ENAME                  SAL DEPTNO  ASAL
----- -------------------- ----- ------ -----
 7369 SMITH                  800     20  2258
 7499 ALLEN                 1600     30  1567
 7521 WARD                  1250     30  1567
 7566 JONES                 2975     20  2258
 7654 MARTIN                1250     30  1567
 7698 BLAKE                 2850     30  1567
 7782 CLARK                 2450     10  2917
 7839 KING                  5000     10  2917
 7844 TURNER                1500     30  1567
 7900 JAMES                  950     30  1567
 7902 FORD                  3000     20  2258

EMPNO ENAME                  SAL DEPTNO  ASAL
----- -------------------- ----- ------ -----
 7934 MILLER                1300     10  2917

12 rows selected.



Q16) 사원번호, 이름, 해당 부서의 지역이 DALLAS 이면 TOP으로 BOSTON이면 BRENCH로 표시하자.


SELECT EMPNO, ENAME,
(CASE WHEN EMP.DEPTNO =
(SELECT DEPTNO FROM DEPT WHERE LOC = 'DALLAS') THEN 'TOP'
WHEN EMP.DEPTNO = (SELECT DEPTNO FROM DEPT WHERE LOC = 'BOSTON') THEN 'BRENCH'
ELSE 'NON-SPECIFIED' END ) AS LOCATION
FROM EMP;

 

SQL> SELECT EMPNO, ENAME,
  2  (CASE WHEN EMP.DEPTNO =
  3  (SELECT DEPTNO FROM DEPT WHERE LOC = 'DALLAS') THEN 'TOP'
  4  WHEN EMP.DEPTNO = (SELECT DEPTNO FROM DEPT WHERE LOC = 'BOSTON') THEN 'BRENCH'
  5  ELSE 'NON-SPECIFIED' END) AS LOCATION
  6  FROM EMP;

EMPNO ENAME                LOCATION
----- -------------------- --------------------------
 7369 SMITH                TOP
 7499 ALLEN                NON-SPECIFIED
 7521 WARD                 NON-SPECIFIED
 7566 JONES                TOP
 7654 MARTIN               NON-SPECIFIED
 7698 BLAKE                NON-SPECIFIED
 7782 CLARK                NON-SPECIFIED
 7839 KING                 NON-SPECIFIED
 7844 TURNER               NON-SPECIFIED
 7900 JAMES                NON-SPECIFIED
 7902 FORD                 TOP

EMPNO ENAME                LOCATION
----- -------------------- --------------------------
 7934 MILLER               NON-SPECIFIED

12 rows selected.

SQL>


Q17) ORDER BY 절에 서브쿼리 사용한 경우

EMP테이블에 사원번호, 사원이름, 부서번호, 입사일을 출력하되 본인 부서명이 큰값이 나오도록 정렬하자.
SELECT EMPNO, ENAME, DEPTNO, HIREDATE
FROM EMP E
ORDER BY (SELECT DNAME
FROM DEPT
WHERE DEPTNO = E.DEPTNO)DESC;

 

SQL> SELECT EMPNO, ENAME, DEPTNO, HIREDATE
  2  FROM EMP E
  3  ORDER BY (SELECT DNAME
  4             FROM DEPT
  5             WHERE DEPTNO = E.DEPTNO) DESC;

EMPNO ENAME                DEPTNO HIREDATE
----- -------------------- ------ --------
 7698 BLAKE                    30 81/05/01
 7900 JAMES                    30 81/12/03
 7844 TURNER                   30 81/09/08
 7654 MARTIN                   30 81/09/28
 7521 WARD                     30 81/02/22
 7499 ALLEN                    30 81/02/20
 7902 FORD                     20 81/12/03
 7566 JONES                    20 81/04/02
 7369 SMITH                    20 80/12/17
 7934 MILLER                   10 82/01/23
 7839 KING                     10 81/11/17

EMPNO ENAME                DEPTNO HIREDATE
----- -------------------- ------ --------
 7782 CLARK                    10 81/06/09

12 rows selected.

SQL>

 

 



□ EXISTS 연산자

  : 서브쿼리의 결과 집합에 행이 있는지 유무를 검사.

Q18) 사원테이블에서 부하직원을 가지고 있는 사원의 사원번호, 이름, 직업, 입사일자를 리턴하자.

 

SELECT EMPNO, ENAME, JOB, HIREDATE
FROM EMP E
WHERE EXISTS (SELECT 1
                    FROM EMP
                    WHERE E.EMPNO = MGR)
ORDER BY EMPNO;

 

SQL> SELECT EMPNO, ENAME, JOB, HIREDATE
  2  FROM EMP E
  3  WHERE EXISTS (SELECT 1
  4               FROM EMP
  5               WHERE E.EMPNO = MGR)
  6  ORDER BY EMPNO;

EMPNO ENAME                JOB                HIREDATE
----- -------------------- ------------------ --------
 7566 JONES                MANAGER            81/04/02
 7698 BLAKE                MANAGER            81/05/01
 7782 CLARK                MANAGER            81/06/09
 7839 KING                 PRESIDENT          81/11/17
 7902 FORD                 ANALYST            81/12/03

SQL>

 

 

□  WITH절 

  : 질의를 쉽게 만든다. 반복실행시에 한번만 실행된다.


Q19) WITH절을 이용해서 전체 부서의 총 급여보다 총급여가 많은 부서의 부서이름, 총 급여를 조회하자.
       = 전체 부서의 평균급여보다 부서별 총 급여가 많은 부서 이름, 총 급여 

WITH
DEPT_COSTS AS(SELECT DNAME, SUM(SAL) AS DEPT_TOTAL
                      FROM EMP E, DEPT D
                      WHERE E.DEPTNO = D.DEPTNO
                      GROUP BY D.DNAME
                      ),
AVG_COST AS(
                   SELECT SUM(DEPT_TOTAL)/ COUNT(*)AS DEPT_AVG
                   FROM DEPT_COSTS
                   )
SELECT *
FROM DEPT_COSTS
WHERE DEPT_TOTAL > (SELECT DEPT_AVG
                               FROM AVG_COST)
ORDER BY DNAME;

 

SQL> WITH
  2  DEPT_COSTS AS(SELECT DNAME, SUM(SAL) AS DEPT_TOTAL
  3                        FROM EMP E, DEPT D
  4                        WHERE E.DEPTNO = D.DEPTNO
  5                        GROUP BY D.DNAME
  6                        ),
  7  AVG_COST AS(
  8                     SELECT SUM(DEPT_TOTAL)/ COUNT(*)AS DEPT_AVG
  9                     FROM DEPT_COSTS
 10                     )
 11  SELECT *
 12  FROM DEPT_COSTS
 13  WHERE DEPT_TOTAL > (SELECT DEPT_AVG
 14                                 FROM AVG_COST)
 15  ORDER BY DNAME;

DNAME                        DEPT_TOTAL
---------------------------- ----------
ACCOUNTING                         8750
SALES                              9400

SQL>


😎 알아두기

 : 인라인뷰는 1회용 VS 뷰는 객체


□ 계층형쿼리

  - START WITH 절을 이용한 시작지점
  - CONNECT BY 절을 이용한 트리진행 방향 설정 / 조건절을 이용해서 데이터 제거
  - LEVEL 의사열의 활용
  - PRIOR 키워드
  - WHERE 조건절 활용해서 데이터 제거

 


[형식]


SELECT [LEVEL] COLUMN1, COLUMN2 , , ,
FROM TABLE1 MAIN
WHERE
[START WITH CONDITION] → 시작할 조건 명시, COLUMN1 = VALUE
[CONNECT BY PRIOR CONDITION];
CONNECT BY PRIOR PARENT KEY = CHLD KEY
CONNECT BY PRIOR PARENT KEY = PARENT KEY

 

 

Q20) SCOTT 계정의 상관관계


SELECT ENAME || '  REPORTS TO  ' || PRIOR ENAME "WALK"
FROM EMP
START WITH ENAME = 'KING'
CONNECT BY PRIOR EMPNO = MGR;

 

SQL> SELECT ENAME || '  REPORTS TO  ' || PRIOR ENAME "WALK"
  2  FROM EMP
  3  START WITH ENAME = 'KING'
  4  CONNECT BY PRIOR EMPNO = MGR;

WALK
--------------------------------------------------------------------
KING  REPORTS TO
JONES  REPORTS TO  KING
FORD  REPORTS TO  JONES
SMITH  REPORTS TO  FORD
BLAKE  REPORTS TO  KING
ALLEN  REPORTS TO  BLAKE
WARD  REPORTS TO  BLAKE
MARTIN  REPORTS TO  BLAKE
TURNER  REPORTS TO  BLAKE
JAMES  REPORTS TO  BLAKE
CLARK  REPORTS TO  KING

WALK
--------------------------------------------------------------------
MILLER  REPORTS TO  CLARK

12 rows selected.



Q21) SMITH 기준으로 BOTTON UP 방향으로 매니저 정보를 출력해보자.


SELECT ENAME, JOB, MGR
FROM EMP
START WITH ENAME = 'SMITH'
CONNECT BY PRIOR MGR = EMPNO;

 

SQL> SELECT ENAME, JOB, MGR
  2  FROM EMP
  3  START WITH ENAME = 'SMITH'
  4  CONNECT BY PRIOR MGR = EMPNO;

ENAME                JOB                  MGR
-------------------- ------------------ -----
SMITH                CLERK               7902
FORD                 ANALYST             7566
JONES                MANAGER             7839
KING                 PRESIDENT

SQL>


Q22) 트리모양으로 계층 확인

 

SELECT LPAD(' ', 4*LEVEL-4)||ENAME ORG_CHART, LEVEL, EMPNO, MGR, DEPTNO
FROM EMP
START WITH MGR IS NULL
CONNECT BY PRIOR EMPNO = MGR;

 

SQL> SELECT LPAD(' ', 4*LEVEL-4)||ENAME ORG_CHART, LEVEL, EMPNO, MGR, DEPTNO
  2  FROM EMP
  3  START WITH MGR IS NULL
  4  CONNECT BY PRIOR EMPNO = MGR;

ORG_CHART              LEVEL   EMPNO     MGR  DEPTNO
-------------------- ------- ------- ------- -------
KING                       1    7839              10
    JONES                  2    7566    7839      20
        FORD               3    7902    7566      20
            SMITH          4    7369    7902      20
    BLAKE                  2    7698    7839      30
        ALLEN              3    7499    7698      30
        WARD               3    7521    7698      30
        MARTIN             3    7654    7698      30
        TURNER             3    7844    7698      30
        JAMES              3    7900    7698      30
    CLARK                  2    7782    7839      10

ORG_CHART              LEVEL   EMPNO     MGR  DEPTNO
-------------------- ------- ------- ------- -------
        MILLER             3    7934    7782      10

12 rows selected.



Q23) SMITH를 삭제하자


SELECT DEPTNO, EMPNO, ENAME, JOB, SAL
FROM EMP
WHERE ENAME != 'SMITH'
START WITH MGR IS NULL
CONNECT BY PRIOR EMPNO = MGR;

 

SQL> SELECT DEPTNO, EMPNO, ENAME, JOB, SAL
  2  FROM EMP
  3  WHERE ENAME != 'SMITH'
  4  START WITH MGR IS NULL
  5  CONNECT BY PRIOR EMPNO = MGR;

 DEPTNO   EMPNO ENAME                JOB                    SAL
------- ------- -------------------- ------------------ -------
     10    7839 KING                 PRESIDENT             5000
     20    7566 JONES                MANAGER               2975
     20    7902 FORD                 ANALYST               3000
     30    7698 BLAKE                MANAGER               2850
     30    7499 ALLEN                SALESMAN              1600
     30    7521 WARD                 SALESMAN              1250
     30    7654 MARTIN               SALESMAN              1250
     30    7844 TURNER               SALESMAN              1500
     30    7900 JAMES                CLERK                  950
     10    7782 CLARK                MANAGER               2450
     10    7934 MILLER               CLERK                 1300

11 rows selected.

SQL>


Q24) BRANCH 삭제하기

 

SELECT DEPTNO, EMPNO, ENAME, JOB, SAL
FROM EMP
START WITH MGR IS NULL
CONNECT BY PRIOR EMPNO = MGR AND ENAME != 'JONES'

 

SQL> SELECT DEPTNO, EMPNO, ENAME, JOB, SAL
  2  FROM EMP
  3  START WITH MGR IS NULL
  4  CONNECT BY PRIOR EMPNO = MGR AND ENAME != 'JONES'
  5  ;

 DEPTNO   EMPNO ENAME                JOB                    SAL
------- ------- -------------------- ------------------ -------
     10    7839 KING                 PRESIDENT             5000
     30    7698 BLAKE                MANAGER               2850
     30    7499 ALLEN                SALESMAN              1600
     30    7521 WARD                 SALESMAN              1250
     30    7654 MARTIN               SALESMAN              1250
     30    7844 TURNER               SALESMAN              1500
     30    7900 JAMES                CLERK                  950
     10    7782 CLARK                MANAGER               2450
     10    7934 MILLER               CLERK                 1300

9 rows selected.


Q25) 계층형 쿼리 정렬

 

SELECT LPAD(' ', 4*LEVEL-4)||ENAME ORG_CHART, LEVEL, EMPNO, MGR, DEPTNO
FROM EMP
START WITH MGR IS NULL
CONNECT BY PRIOR EMPNO = MGR
ORDER BY ENAME;

 

SQL> SELECT LPAD(' ', 4*LEVEL-4)||ENAME ORG_CHART, LEVEL, EMPNO, MGR, DEPTNO
  2  FROM EMP
  3  START WITH MGR IS NULL
  4  CONNECT BY PRIOR EMPNO = MGR
  5  ORDER BY ENAME;

ORG_CHART              LEVEL   EMPNO     MGR  DEPTNO
-------------------- ------- ------- ------- -------
        ALLEN              3    7499    7698      30
    BLAKE                  2    7698    7839      30
    CLARK                  2    7782    7839      10
        FORD               3    7902    7566      20
        JAMES              3    7900    7698      30
    JONES                  2    7566    7839      20
KING                       1    7839              10
        MARTIN             3    7654    7698      30
        MILLER             3    7934    7782      10
            SMITH          4    7369    7902      20
        TURNER             3    7844    7698      30

ORG_CHART              LEVEL   EMPNO     MGR  DEPTNO
-------------------- ------- ------- ------- -------
        WARD               3    7521    7698      30

12 rows selected.

 


SELECT LPAD(' ', 4*LEVEL-4)||ENAME ORG_CHART, LEVEL, EMPNO, MGR, DEPTNO
FROM EMP
START WITH MGR IS NULL
CONNECT BY PRIOR EMPNO = MGR
ORDER SIBLINGS BY ENAME;

 

SQL> SELECT LPAD(' ', 4*LEVEL-4)||ENAME ORG_CHART, LEVEL, EMPNO, MGR, DEPTNO
  2  FROM EMP
  3  START WITH MGR IS NULL
  4  CONNECT BY PRIOR EMPNO = MGR
  5  ORDER SIBLINGS BY ENAME;

ORG_CHART              LEVEL   EMPNO     MGR  DEPTNO
-------------------- ------- ------- ------- -------
KING                       1    7839              10
    BLAKE                  2    7698    7839      30
        ALLEN              3    7499    7698      30
        JAMES              3    7900    7698      30
        MARTIN             3    7654    7698      30
        TURNER             3    7844    7698      30
        WARD               3    7521    7698      30
    CLARK                  2    7782    7839      10
        MILLER             3    7934    7782      10
    JONES                  2    7566    7839      20
        FORD               3    7902    7566      20

ORG_CHART              LEVEL   EMPNO     MGR  DEPTNO
-------------------- ------- ------- ------- -------
            SMITH          4    7369    7902      20

12 rows selected.

 



Q26) 계층형 연결 경로 확인

SELECT LPAD(' ', 4*LEVEL-4)||ENAME ORG_CHART, JOB,
SYS_CONNECT_BY_PATH(ENAME, '-')
FROM EMP
START WITH MGR IS NULL
CONNECT BY PRIOR EMPNO = MGR;

 

SQL> SELECT LPAD(' ', 4*LEVEL-4)||ENAME ORG_CHART, JOB,
  2  SYS_CONNECT_BY_PATH(ENAME, '-')
  3  FROM EMP
  4  START WITH MGR IS NULL
  5  CONNECT BY PRIOR EMPNO = MGR;

ORG_CHART            JOB
-------------------- ------------------
SYS_CONNECT_BY_PATH(ENAME,'-')
--------------------------------------------------------------------------------
KING                 PRESIDENT
-KING

    JONES            MANAGER
-KING-JONES

        FORD         ANALYST
-KING-JONES-FORD


ORG_CHART            JOB
-------------------- ------------------
SYS_CONNECT_BY_PATH(ENAME,'-')
--------------------------------------------------------------------------------
            SMITH    CLERK
-KING-JONES-FORD-SMITH

    BLAKE            MANAGER
-KING-BLAKE

        ALLEN        SALESMAN
-KING-BLAKE-ALLEN


ORG_CHART            JOB
-------------------- ------------------
SYS_CONNECT_BY_PATH(ENAME,'-')
--------------------------------------------------------------------------------
        WARD         SALESMAN
-KING-BLAKE-WARD

        MARTIN       SALESMAN
-KING-BLAKE-MARTIN

        TURNER       SALESMAN
-KING-BLAKE-TURNER


ORG_CHART            JOB
-------------------- ------------------
SYS_CONNECT_BY_PATH(ENAME,'-')
--------------------------------------------------------------------------------
        JAMES        CLERK
-KING-BLAKE-JAMES

    CLARK            MANAGER
-KING-CLARK

        MILLER       CLERK
-KING-CLARK-MILLER


12 rows selected.


Q27) 계층형 쿼리에서 해당하는 로우가 자식노드가 있는지 없는지 여부를 체크
  : 자식노드가 있을 경우 0 , 자식노드가 없을 경우 1


SELECT LPAD(' ', 4*LEVEL-4)||ENAME ORG_CHART, JOB,
CONNECT_BY_ISLEAF
FROM EMP
START WITH MGR IS NULL
CONNECT BY PRIOR EMPNO = MGR;

 

SQL> SELECT LPAD(' ', 4*LEVEL-4)||ENAME ORG_CHART, JOB,
  2  CONNECT_BY_ISLEAF
  3  FROM EMP
  4  START WITH MGR IS NULL
  5  CONNECT BY PRIOR EMPNO = MGR;

ORG_CHART            JOB                CONNECT_BY_ISLEAF
-------------------- ------------------ -----------------
KING                 PRESIDENT                          0
    JONES            MANAGER                            0
        FORD         ANALYST                            0
            SMITH    CLERK                              1
    BLAKE            MANAGER                            0
        ALLEN        SALESMAN                           1
        WARD         SALESMAN                           1
        MARTIN       SALESMAN                           1
        TURNER       SALESMAN                           1
        JAMES        CLERK                              1
    CLARK            MANAGER                            0

ORG_CHART            JOB                CONNECT_BY_ISLEAF
-------------------- ------------------ -----------------
        MILLER       CLERK                              1

12 rows selected.


Q28) LEAF만 보여주기

 

  WHERE CONNECT_BY_ISLEAF = 1 : ROW가 자식노드를 가지고 있지 않을때 LEAF NODE이다.
  WHERE CONNECT_BY_ISLEAF = 0 : ROW가 자식노드를 가지고 있지 않을 때 LEAF NODE가 아니다.

 


SELECT LPAD(' ', 4*LEVEL-4)||ENAME ORG_CHART, JOB
FROM EMP
WHERE CONNECT_BY_ISLEAF = 1 
START WITH MGR IS NULL
CONNECT BY PRIOR EMPNO = MGR;

 

SQL> SELECT LPAD(' ', 4*LEVEL-4)||ENAME ORG_CHART, JOB
  2  FROM EMP
  3  WHERE CONNECT_BY_ISLEAF = 1
  4  START WITH MGR IS NULL
  5  CONNECT BY PRIOR EMPNO = MGR;

ORG_CHART            JOB
-------------------- ------------------
            SMITH    CLERK
        ALLEN        SALESMAN
        WARD         SALESMAN
        MARTIN       SALESMAN
        TURNER       SALESMAN
        JAMES        CLERK
        MILLER       CLERK

7 rows selected.

 


SELECT LPAD(' ', 4*LEVEL-4)||ENAME ORG_CHART, JOB
FROM EMP
WHERE CONNECT_BY_ISLEAF = 0
START WITH MGR IS NULL
CONNECT BY PRIOR EMPNO = MGR;

 

SQL> SELECT LPAD(' ', 4*LEVEL-4)||ENAME ORG_CHART, JOB
  2  FROM EMP
  3  WHERE CONNECT_BY_ISLEAF = 0
  4  START WITH MGR IS NULL
  5  CONNECT BY PRIOR EMPNO = MGR;

ORG_CHART            JOB
-------------------- ------------------
KING                 PRESIDENT
    JONES            MANAGER
        FORD         ANALYST
    BLAKE            MANAGER
    CLARK            MANAGER




 

'|Playdata_study > SQL.Oracle' 카테고리의 다른 글

210527_DB5(SQL) / 트랜잭션  (0) 2021.05.27
210526_DB4 (SQL) / INSERT, UPDATE, DELETE, MARGE  (0) 2021.05.26
210524 _DB3 (SQL) / 분석함수, JOIN  (0) 2021.05.24
210521 _DB3 (SQL)  (0) 2021.05.22
210518_DB2 (SQL)  (0) 2021.05.19

댓글