지구정복

[SQLD] 23. 서브 쿼리 본문

자격증 정복/SQLD

[SQLD] 23. 서브 쿼리

eeaarrtthh 2020. 11. 10. 09:59
728x90
반응형

서브쿼리 개요

  • 서브쿼리(Subquery)란 하나의 SQL문안에 포함되어 있는 또 다른 SQL문을 말한다.

서브쿼리를 사용할 때 다음 사항에 주의해야 한다.
① 서브쿼리를 괄호로 감싸서 사용한다.
② 서브쿼리는 단일 행(Single Row) 또는 복수 행(Multiple Row) 비교 연산자와 함께 사용 가능하다. 단일 행 비교 연산자는 서브쿼리의 결과가 반드시 1건 이하이어야 하고
복수 행 비교 연산자는 서브쿼리의 결과 건수와 상관 없다.
③ 서브쿼리에서는 ORDER BY를 사용하지 못한다. ORDER BY절은 SELECT절에서 오직 한 개만 올 수 있기 때문에 ORDER BY절은 메인쿼리의 마지막 문장에 위치해야 한다.

서브쿼리가 SQL문에서 사용이 가능한 곳은 다음과 같다.

  • SELECT 절
  • FROM 절
  • WHERE 절
  • HAVING 절
  • ORDER BY 절
  • INSERT문의 VALUES 절
  • UPDATE문의 SET 절

서브쿼리 분류

1. 단일행 서브쿼리

  • 서브쿼리가 단일 행 비교 연산자(=, <, <=, >, >=, <>)와 함께 사용할 때는 서브쿼리의 결과 건수가 반드시 1건 이하이어야 한다.
  • 서브쿼리의 결과 건수가 2건 이상을 반환하면 SQL문은 실행시간(Run Time) 오류가 발생한다.

EX) 정남일과 같은 팀코드를 가진 선수명, 포지션, 백넘버를 출력하시오. (서브쿼리 사용)

SELECT PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버 
FROM PLAYER 
WHERE TEAM_ID = (
    SELECT TEAM_ID 
    FROM PLAYER 
    WHERE PLAYER_NAME = '정남일') 
ORDER BY PLAYER_NAME;

서브쿼리가 먼저 실행되어서 '정남일'이 소속되어 있는 팀코드를 반환하고 이 반환값과 같은 팀코드를 가진 선수들의 정보를 출력한다.

만약 정남일 선수 중에 동명이인이 있을 경우 2건이 되어 오류가 날 수 있다.

이번에는 선수들 중에서 키가 평균 이하인 선수들의 정보를 출력하는 문제를 가지고 그룹함수를 사용한 서브쿼리를 알아보도록 한다.

SELECT PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키
FROM PLAYER
WHERE HEIGHT <= (
    SELECT AVG(HEIGHT)
    FROM PLAYER)
ORDER BY HEIGHT;

 

 

2. 다중행 서브쿼리

  • 서브쿼리의 결과가 2건 이상 반환될 수 있다면 반드시 다중 행 비교 연산자(IN, ALL, ANY, SOME)와 함께 사용해야 한다. 그렇지 않으면 SQL문은 오류를 반환한다. 다중 행 비교 연산자는 다음과 같다.

EX) 정현수가 있는 팀의 연고지명, 팀명, 영문팀명을 출력하시오. (서브쿼리 + IN 비교연산자 사용)

SELECT REGION_NAME 연고지명, TEAM_NAME 팀명, E_TEAM_NAME 영문팀명 
FROM TEAM 
WHERE TEAM_ID = (
    SELECT TEAM_ID 
    FROM PLAYER 
    WHERE PLAYER_NAME = '정현수') 
ORDER BY TEAM_NAME;

-- ORA-01427: 단일 행 하위 질의에 2개 이상의 행이 리턴되었다.

SELECT REGION_NAME 연고지명, TEAM_NAME 팀명, E_TEAM_NAME 영문팀명 
FROM TEAM 
WHERE TEAM_ID IN (
    SELECT TEAM_ID 
    FROM PLAYER 
    WHERE PLAYER_NAME = '정현수') 
ORDER BY TEAM_NAME;

위 결과를 보면 정현수 선수가 2명임을 알 수 있다. 따라서 다중행 서브쿼리를 통해 출력해야한다.

 

3. 다중 칼럼 서브쿼리

  • 다중 칼럼 서브쿼리는 서브쿼리의 결과로 여러 개의 칼럼이 반환되어 메인쿼리의 조건과 동시에 비교되는 것을 의미한다.
  • 이 기능은 SQL Server에서는 지원되지 않는 기능이다.

EX) 각 팀의 키가 가장 작은 선수들의 팀코드, 선수명, 포지션, 백넘버, 키를 출력하시오.

(다중 컬럼 서브쿼리 및 IN연산자 사용 / 팀코드와 선수명을 오름차순으로 정렬)

SELECT TEAM_ID 팀코드, PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키
FROM PLAYER
WHERE (TEAM_ID, HEIGHT) IN (
    SELECT TEAM_ID, MIN(HEIGHT) 
    FROM PLAYER
    GROUP BY TEAM_ID)
ORDER BY 1, 2;

4. 연관 서브쿼리

  • 연관 서브쿼리(Correlated Subquery)는 서브쿼리 내에 메인쿼리 칼럼이 사용된 서브쿼리이다

EX) 선수 자신이 속한 팀의 평균 키보다 작은 선수들의 정보를 출력하는 SQL문을 연관 서브쿼리를 이용해서 작성해 보면 다음과 같다

SELECT T.TEAM_NAME 팀명, M.PLAYER_NAME 선수명, M.POSITION 포지션, M.BACK_NO 백넘버, M.HEIGHT 키 
FROM PLAYER M, TEAM T 
WHERE M.TEAM_ID = T.TEAM_ID AND M.HEIGHT < (
    SELECT AVG(S.HEIGHT) 
    FROM PLAYER S 
    WHERE S.TEAM_ID = M.TEAM_ID AND S.HEIGHT IS NOT NULL 
    GROUP BY S.TEAM_ID ) 
ORDER BY 선수명;

EXISTS 서브쿼리

  • EXISTS 서브쿼리의 특징은 아무리 조건을 만족하는 건이 여러 건이더라도 조건을 만족하는 1건만 찾으면 추가적인 검색을 진행하지 않는다 (교재내용)
  • EXISTS 연산자는 Subquery 데이터가 존재하는가를 체크해 존재 여부(TRUE,FALSE)를 결과로 반환한다.
  • EXISTS절에는 반드시 메인 쿼리와 연결이 되는 조인 조건을 가지고 있어야 한다.
  • subquery에서 결과 행을 찾으면, inner query 수행을 중단하고 TRUE를 반환한다.

다음은 EXISTS 서브쿼리를 사용하여 '20120501' 부터 '20120502' 사이에 경기가 있는 경기장을 조회하는 SQL문이다.

SELECT STADIUM_ID ID, STADIUM_NAME 경기장명 
FROM STADIUM A WHERE EXISTS (
    SELECT 1 
    FROM SCHEDULE X 
    WHERE X.STADIUM_ID = A.STADIUM_ID AND X.SCHE_DATE BETWEEN '20120501' AND '20120502'
)

5. 그밖에 위치에서 사용하는 서브쿼리

가. SELECT 절에 서브쿼리 사용하기

다음은 SELECT 절에서 사용하는 서브쿼리인 스칼라 서브쿼리(Scalar Subquery)에 대해서 알아본다.
스칼라 서브쿼리는 한 행, 한 칼럼(1 Row 1 Column)만을 반환하는 서브쿼리를 말한다.
스칼라 서브쿼리는 칼럼을 쓸 수 있는 대부분의 곳에서 사용할 수 있다.

EX) 팀별 평균키를 알아내서 선수명과 키를 출력하시오.(서브쿼리를 SELECT문에 집어넣을 것)

SELECT PLAYER_NAME 선수명, HEIGHT 키, (
    SELECT AVG(HEIGHT) 
    FROM PLAYER X 
    WHERE X.TEAM_ID = P.TEAM_ID) 팀평균키 FROM PLAYER P

나. FROM 절에서 서브쿼리 사용하기

  • FROM 절에서 사용되는 서브쿼리를 인라인 뷰(Inline View)라고 한다.
  • SQL문이 실행될 때만 임시적으로 생성되는 동적인 뷰이기 때문에 데이터베이스에 해당 정보가 저장되지 않는다.
  • 그래서 일반적인 뷰를 정적 뷰(Static View)라고 하고 인라인 뷰를 동적 뷰(Dynamic View)라고도 한다
SELECT T.TEAM_NAME 팀명, P.PLAYER_NAME 선수명, P.BACK_NO 백넘버 
FROM ( 
    SELECT TEAM_ID, PLAYER_NAME, BACK_NO 
    FROM PLAYER 
    WHERE POSITION = 'MF') P, TEAM T 
WHERE P.TEAM_ID = T.TEAM_ID 
ORDER BY 선수명;

<Oracle>

SELECT PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키 
FROM ( SELECT PLAYER_NAME, POSITION, BACK_NO, HEIGHT 
       FROM PLAYER 
       WHERE HEIGHT IS NOT NULL 
       ORDER BY HEIGHT DESC) 
WHERE ROWNUM <= 5;

<SQL Server>

SELECT TOP(5) PLAYER_NAME AS 선수명, POSITION AS 포지션, BACK_NO AS 백넘버, HEIGHT AS 키 
FROM PLAYER 
WHERE HEIGHT IS NOT NULL 
ORDER BY HEIGHT DESC

다. HAVING 절에서 서브쿼리 사용하기

HAVING 절은 그룹함수와 함께 사용될 때 그룹핑된 결과에 대해 부가적인 조건을 주기 위해서 사용한다

SELECT P.TEAM_ID 팀코드, T.TEAM_NAME 팀명, AVG(P.HEIGHT) 평균키 
FROM PLAYER P, TEAM T 
WHERE P.TEAM_ID = T.TEAM_ID 
GROUP BY P.TEAM_ID, T.TEAM_NAME HAVING AVG(P.HEIGHT) < 
   (SELECT AVG(HEIGHT) 
   FROM PLAYER 
   WHERE TEAM_ID ='K02')

라. UPDATE문의 SET 절에서 사용하기

UPDATE TEAM A SET A.STADIUM_NAME = 
(SELECT X.STADIUM_NAME 
 FROM STADIUM X 
 WHERE X.STADIUM_ID = A.STADIUM_ID);

마. INSERT문의 VALUES절에서 사용하기

INSERT INTO PLAYER(PLAYER_ID, PLAYER_NAME, TEAM_ID) 
VALUES((SELECT TO_CHAR(MAX(TO_NUMBER(PLAYER_ID))+1) 
        FROM PLAYER), '홍길동', 'K06');

6. 뷰(View)

  • 테이블은 실제로 데이터를 가지고 있는 반면, 뷰(View)는 실제 데이터를 가지고 있지 않다.
  • 뷰는 단지 뷰 정의(View Definition)만을 가지고 있다.
  • 질의에서 뷰가 사용되면 뷰 정의를 참조해서 DBMS 내부적으로 질의를 재작성(Rewrite)하여 질의를 수행한다.
  • 뷰는 실제 데이터를 가지고 있지 않지만 테이블이 수행하는 역할을 수행하기 때문에 가상 테이블(Virtual Table)이라고도 한다.

VIEW 생성

CREATE VIEW V_PLAYER_TEAM 
  AS SELECT P.PLAYER_NAME, P.POSITION, P.BACK_NO, P.TEAM_ID, T.TEAM_NAME 
  FROM PLAYER P, TEAM T 
  WHERE P.TEAM_ID = T.TEAM_ID; 
SELECT * FROM VIEW V_PLAYER_TEAM

VIEW 삭제

DROP VIEW V_PLAYER_TEAM; 
DROP VIEW V_PLAYER_TEAM_FILTER;

 

 

정리

------서브쿼리
--서브쿼리란 하나의 SQL문 안에 포함되어 있는 또 다른 SQL문을 의미한다.
--조인은 집한간의 곱(PRODUCT) 관계이기 때문에 항상 관계가 큰 쪽의 집합으로 생성된다.
--예를들어 조직(1)과 사원(N) 테이블이 조인하면 결과는 사원레벨(N)의 집합이 생성된다.
--하지만 서브쿼리는 무조건 메인쿼리 레벨이 된다. 서브쿼리가 N이든 1이든 메인쿼리 레벨로 형성된다.

----서브쿼리 주의사항은 다음과 같다.
--1. 괄호로 감싸서 사용한다.
--2. 단일 행 또는 복수 행 비교 연산자와 함께 사용가능하다. 
--단일행 비교 연산자는 서브쿼리의 결과가 반드시 1건이어야하고, 
--복수 행 비교 연산자는 서브쿼리의 결과 건수와 상관없다.
--3. 서브쿼리에서는 ORDER BY를 사용못한다. ORDER BY는 SELECT절에서 오직 한 개만 올 수 있다.

----서브쿼리가 사용 가능한 곳은 SELECT, FROM, WHERE HAVING, ORDER BY, INSERT의 VALUES, UPDATE

----동작하는 방식에 따른 서브쿼리 분류
--비연관 서브쿼리: 서브쿼리가 메인쿼리 컬럼을 가지고 있지 않는 형태, 
--연관 서브쿼리: 서브쿼리가 메인쿼리 컬럼을 가지고 있는 형태, 일반적으로 메인쿼리가 먼저 수행되어 읽혀진 
--데이터를 서브쿼리에서 조건이 맞는지 확인하고자 할 때 사용된다.

----반환되는 데이터의 형태에 따른 서브쿼리 분류
--단일행서브쿼리: 서브쿼리의 실행 결과가 항상 1건 이하인 서브쿼리를 의미
--단일 행 비교 연산자에는 =, <, <=, >, >=, <>이 있다.
--다중행서브쿼리: 서브쿼리의 실행결과가 여러 건인 서브쿼리를 의미
--다중 행 비교 연산자에는 IN, ALL, ANY, SOM, EXISTS가 있다.
--다중 컬럼 서브쿼리: 서브쿼리의 실행 결과로 여러 컬럼을 반환한다. 
--서브쿼리와 메인쿼리에서 비교하고자하는 컬럼개수와 컬럼의 위치가 동일해야 한다.

----1. 단일 행 서브쿼리
--단일 행 서브쿼리의 예로 '정남일'선수가 소속된 팀의 선수들에 대한 정보를 출력해보자.
SELECT PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버
FROM PLAYER
WHERE TEAM_ID = (
    SELECT TEAM_ID
    FROM PLAYER
    WHERE PLAYER_NAME = '정남일')
ORDER BY 1;
--단일 행 서브쿼리는 무조건 서브쿼리의 결과가 1건이어야 하므로 만약 정남일 선수가 동명이인으로 2명이상이었다면
--오류가 났을 것이다.
--다음으로 선수들의 평균키를 알아내는 서브쿼리로 키가 평균 이하의 선수들의 정보를 출력해보자.
SELECT PLAYER_NAME, POSITION, BACK_NO, HEIGHT
FROM PLAYER
WHERE HEIGHT <= (
    SELECT AVG(HEIGHT)
    FROM PLAYER)
ORDER BY 4;

----2. 다중 행 서브쿼리
--IN: 서브쿼리의 결과에 존재하는 임의의 값과 동일한 조건을 의미한다.
--ALL: 서브쿼리의 결과에 존재하는 모든 값을 만족하는 조건을 의미한다. 
--ANY: 서브쿼리의 결과에 존재하는 어느 하나의 값이라도 만족하는 조건을 의미한다.
--EXISTS: 서브쿼리의 결과를 만족하는 값이 존재하는지 여부를 확인하는 조건을 의미한다.
--서브쿼리의 만족하는 건이 여러 건이더라도 1건만 찾으면 검색을 멈춘다.
--정현수라는 선수가 소속되어 있는 팀 정보를 출력하는 서브쿼리는 다음과 같다.
SELECT REGION_NAME, TEAM_NAME, E_TEAM_NAME
FROM TEAM
WHERE TEAM_ID = (
    SELECT TEAM_ID
    FROM PLAYER
    WHERE PLAYER_NAME = '정현수')
ORDER BY 2;
--위의 서브쿼리를 실행하면 단일 행 연산자=를 사용해서 1건 이상이 출력돼서 오류가 난다.
--이를 다중 행 연산자 IN으로 바꿔보자.
SELECT REGION_NAME, TEAM_NAME, E_TEAM_NAME
FROM TEAM
WHERE TEAM_ID IN (
    SELECT TEAM_ID
    FROM PLAYER
    WHERE PLAYER_NAME = '정현수')
ORDER BY 2;
--성공적으로 실행이 된다.


----3. 다중 컬럼 서브쿼리
--서브쿼리의 결과로 여러 개의 컬럼이 반환되어 메인쿼리의 조건과 동시에 비교되는 것을 의미한다.
--소속팀별 키가 가장 작은 사람들의 정보를 출력해보자.
SELECT TEAM_ID, PLAYER_NAME, POSITION, BACK_NO, HEIGHT
FROM PLAYER
WHERE (TEAM_ID, HEIGHT) IN (
    SELECT TEAM_ID, MIN(HEIGHT)
    FROM PLAYER
    GROUP BY TEAM_ID)
ORDER BY 1, 5;



----4. 연관 서브쿼리
--서브쿼리 내에 메인쿼리 컬럼이 사용된 서브쿼리이다. 
--선수 자신이 속한 팀의 평균키보다 작은 선수들의 정보를 출력해보자.
SELECT T.TEAM_NAME, M.PLAYER_NAME, M.POSITION, M.BACK_NO, M.HEIGHT
FROM PLAYER M, TEAM T
WHERE M.TEAM_ID = T.TEAM_ID AND M.HEIGHT < (
    SELECT AVG(S.HEIGHT)
    FROM PLAYER S
    WHERE S.TEAM_ID = M.TEAM_ID AND S.HEIGHT IS NOT NULL
    GROUP BY S.TEAM_ID)
ORDER BY 1, 5;

--EXISTS 서브쿼리는 항상 연관 서브쿼리로 사용된다. 또한 EXISTS서브쿼리의 특징은 아무리 조건을
--만족하는 건이 여러 건이더라도 조건을 만족하는 1건만 찾으면 추가적인 검색을 진행하지 않는다. 
--다음은 서브쿼리를 이용해서 '20120501'부터 '20120502'사이에 경기가 있는 경기장을 조회하는 SQL문이다.
SELECT STADIUM_ID, STADIUM_NAME
FROM STADIUM A
WHERE EXISTS (
    SELECT 1
    FROM SCHEDULE X
    WHERE X.STADIUM_ID = A.STADIUM_ID AND X.SCHE_DATE BETWEEN '20120501' AND '20120502');
    

--5. 그 밖에 위치에서 사용하는 서브쿼리
--가. SELECT 절에 서브쿼리 사용하기
--이를 스칼라 서브쿼리(Scalar Subquery)라고 한다.
--스칼라 서브쿼리는 한 행, 한 컬럼(1 ROW 1 COULMN)만을 반환하는 서브쿼리이다.
--스칼라 서브쿼리는 컬럼을 쓸 수 있는 대부분의 곳에서 사용가능하다.
--선수 정보와 해당 선수가 속한 팀의 평균 키를 함께 출력하는 예제를 살펴보자.
SELECT PLAYER_NAME, HEIGHT, ROUND((
    SELECT AVG(HEIGHT)
    FROM PLAYER X
    WHERE X.TEAM_ID = P.TEAM_ID), 2)
FROM PLAYER P;

--나. FROM절에서 서브쿼리 사용하기
--이를 인라인 뷰(Inline View)라고 한다. 인라인 뷰를 사용하면 마치 실행 시에 동적으로 생성된
--테이블인 것처럼 사용할 수 있다. 인라인 뷰는 SQL문이 실행될 때만 임시적으로 생성되는 동적 뷰이기 때문에
--데이터베이스에 해당 정보가 저장되지 않는다. 그래서 일반적인 뷰를 정적 뷰(Static View)라고 한다.
--인라인 뷰는 테이블 명이 올 수 있는 곳에서 사용할 수 있다. 
--포지션이 미드필드인 선수들의 소속팀명 및 선수 정보를 출력해보자.
SELECT T.TEAM_NAME, P.PLAYER_NAME, P.BACK_NO, POSITION
FROM (SELECT TEAM_ID, PLAYER_NAME, BACK_NO, POSITION
      FROM PLAYER
      WHERE POSITION = 'MF') P, TEAM T
WHERE P.TEAM_ID = T.TEAM_ID
ORDER BY 2;
--참고로 SQL의 실행순서는 다음과 같다.
--FROM > WHERE > GROUP BY > HAVING > SELECT > ORDER BY
--이번에는 인라인 뷰에서 ORDER BY절을 사용해보자. 
--인라인 뷰에서 먼저 정렬을 수행하고 정렬된 결과 중에서 일부 데이터를 추출하는 것을 TOP-N쿼리라고 한다.
--TOP-N 쿼리를 수행하기 위해서는 정렬 작업과 정렬 결과 중에서 일부 데이터만을 추출할 수 있는 방법이 필요하다.
--ORACLE에서는 ROWNUM이라는 연산자를 통해서 결과로 추출하고자 하는 데이터 건수를 제약할 수 있다.
--TOP-N쿼리를 이용해서 가장 키가 큰 선수 5명을 출력해보자.
SELECT PLAYER_NAME, POSITION, BACK_NO, HEIGHT
FROM (SELECT PLAYER_NAME, POSITION, BACK_NO, HEIGHT
      FROM PLAYER
      WHERE HEIGHT IS NOT NULL
      ORDER BY HEIGHT DESC)
WHERE ROWNUM <= 5;

--다. HAVING절에서 서브쿼리 사용하기
--HAVING절을 그룹함수와 함께 사용될 때 그룹핑된 결과에 대해 부가적인 조건을 주기 위해서 사용한다.
--평균키가 삼성블루윙즈 팀의 평균키보다 작은 팀의 이름과 해당 팀의 평균키를 출력해보자.
SELECT P.TEAM_ID, T.TEAM_NAME, AVG(P.HEIGHT)
FROM PLAYER P, TEAM T
WHERE P.TEAM_ID = T.TEAM_ID
GROUP BY P.TEAM_ID, T.TEAM_NAME
HAVING AVG(P.HEIGHT) < (SELECT AVG(HEIGHT)
                        FROM PLAYER
                        WHERE TEAM_ID='K02');

--라. UPDATE문의 SET절에서 사용하기
--현재 TEAM테이블에는 STADIUM_NAME컬럼이 없다. 여기에 STADIUM_NAME 컬럼을 추가하자.
ALTER TABLE TEAM 
ADD (STADIUM_NAME VARCHAR2(80));
--TEAM 테이블에 추가된 STADIUM_NAME의 값을 STADIUM 테이블을 이용하여 변경하고자 할 때 다음과 같이 작성한다.
UPDATE TEAM A 
SET A.STADIUM_NAME = (SELECT X.STADIUM_NAME
                      FROM STADIUM X
                      WHERE X.STADIUM_ID = A.STADIUM_ID);
                      
--마. INSERT 문의 VALUES절에서 사용하기
--PLAYER테이블에 홍길동이라는 선수를 삽입하고자 한다. 이때 PLAYER_ID에 1을 더한 값으로 넣고자 한다.
--다음과 같이 작성한다.
INSERT INTO PLAYER(PLAYER_ID, PLAYER_NAME, TEAM_ID)
VALUES( (SELECT TO_CHAR(MAX(TO_NUMBER(PLAYER_ID))+1)
         FROM PLAYER), '홍길동', 'K06' );
         
----6. 뷰(VIEW)
--테이블은 실제로 데이터를 가지는 반면, 뷰는 실제 데이터를 가지고 있지 않다. 
--뷰는 단지 뷰 정의만을 가지고 있다. 질의에서 뷰가 사용되면 뷰 정의를 참조해서 DBMS 내부적으로 질의를 재작성하여
--질의를 수행한다. 뷰는 실제 데이터를 가지고 있지 않지만 테이블이 수행하는 역할을 수행하기 때문에
--가상 테이블(Virtual Table)이라고 한다.
--장점은 다음과 같다.
--1. 독립성: 테이블 구조가 변경되어도 뷰를 사용하는 응용프로그램은 변경하지 않아도 된다.
--2. 편리성: 복잡한 질의를 뷰로 생성해서 관련 질의를 단순하게 작성한다. 또한 해당 SQL문을 자주사용할 때 뷰를 이용한다.
--3. 보안성: 숨시고 싶은 정보가 있다면 뷰를 생성할 때 해당 컬럼을 빼고 생성해서 사용자에게 정보를 감춘다.
--뷰는 CREATE VIEW 문을 통해서 생성한다.
CREATE VIEW V_PLAYER_TEAM
AS SELECT P.PLAYER_NAME, P.POSITION, P.BACK_NO, P.TEAM_ID, T.TEAM_NAME
   FROM PLAYER P, TEAM T
   WHERE P.TEAM_ID = T.TEAM_ID;

--뷰는 테이블이 아니라 기존에 존재하는 뷰를 참조해서 생성할수도 있다.
CREATE VIEW V_PLAYER_TEAM_FILTER 
AS SELECT PLAYER_NAME, POSITION, BACK_NO, TEAM_NAME
   FROM V_PLAYER_TEAM
   WHERE POSITION IN ('GK', 'MF');
   
--뷰를 사용하려면 해당 뷰의 이름을 이용하면 된다.
SELECT PLAYER_NAME, POSITION, BACK_NO, TEAM_ID, TEAM_NAME
FROM V_PLAYER_TEAM
WHERE PLAYER_NAME LIKE '황%';

--뷰를 사용하는 경우에 DBMS가 내부적으로 다음과 같은 SQL을 재작성해서 실행한다.
--이는 인라인 뷰와 비슷하다.
SELECT PLAYER_NAME, POSITION, BACK_NO, TEAM_ID, TEAM_NAME
FROM (SELECT P.PLAYER_NAME, P.POSITION, P.BACK_NO, P.TEAM_ID, T.TEAM_NAME
      FROM PLAYER P, TEAM T
      WHERE P.TEAM_ID = T.TEAM_ID)
WHERE PLAYER_NAME LIKE '황%';

--뷰를 제거할 때는 DRO VIEW문을 사용한다.
DROP VIEW V_PLAYER_TEAM;
DROP VIEW V_PLAYER_TEAM_FILTER;


 

 

 

 

 

[출처]

wiki.gurubee.net/pages/viewpage.action?pageId=27427331

728x90
반응형
Comments