뷰는 실제 데이터가 없지만 테이블 역할을 수행하기 때문에 가상 테이블이라고 한다
권한 관리를 통해 보여주고 싶은 데이터가 다를경우 뷰를 이용한다 ( 보안성 )
데이터가 크다면 조인보다 약간 빠르게 볼수 있다.
소괄호 안에 <인라인 뷰>로 만들면 사용하기 편하다
인라인 뷰는 SQL 문이 실행될 때만 임시적으로 생성되는 동적인 뷰
단일 테이블에 기반하면서 집계함수를 사용하지 않은 뷰를 수정하면 테이블도 수정이 된다. 이를 통해 데이터의 무결성이 유지된다.
코드로 알아보자
create view VV -- VV 라는 뷰를 만든다.
as
select empno, ename, hiredate
from emp;
select * from VV where empno > 7500; -- 뷰를 이용해서 쿼리를 작성할수 있다.
create view v_emp2 -- 조인을 해서 뷰로 만든다 ( 복합뷰 )
as
select e.ename, d.dname
from emp e, dept d
where e.deptno = d.deptno;
select * from v_emp2;
지금까지 사용한 SELECT
로 시작하는 쿼리를 '메인쿼리' 라고 한다.
메인쿼리 내부에 쿼리(서브쿼리)를 사용하여 복잡한 SQL문을 작성하게 해준다.
조인과 서브쿼리는 유사하면서 약간의 차이가 있다.
경우에 따라 조인을 사용할지 서브쿼리를 사용할지는 사용자에 판단에 달렸다.
서브쿼리가 가능한곳
서브쿼리에는 ORDER BY
를 사용할 수 없다 (적용이 안된다).
SELECT
다음에 서브쿼리가 오면 < 스칼라 서브쿼리 > 라고 한다.
장점
데이터 메모리가 만들어져서 속도가 조금 더 빠르다
시스템 튜닝시 스칼라 서브쿼리를 이용해서 속도를 개선할 수 있다
( DBA(관리자) 고유영역 : 백업, 복원, 인덱스작업, 테이블, 뷰 생성+튜닝 등.. )
select name,
(select
dname
from dept2 d
where e.DEPTNO = d.dcode
)as dname
from emp2 e;
FROM
다음에 서브쿼리가 오면 < 인라인 뷰 > 라고 한다.
select
e.deptno, d.dname, e.sal
from (
SELECT
deptno, max(sal) as sal
FROM emp group by deptno
) e, dept d
where e.deptno = d.deptno; -- 인라인 뷰를 이용
select
a.deptno, b.dname, max(a.sal) as sal
from emp a join dept b
on a.deptno = b.deptno
group by deptno
order by sal desc; -- 조인을 이용 .. 두 쿼리 모두 같은 결과
select
d.dname, -- 부서별 최대키와 , 부서별 최대키를 가진 이의 이름, 그의 키
a.m_h max_height,
s.name,
s.height
from ( select
deptno1, max(height) m_h
from student
group by deptno1
) a join student s join department d
on s.deptno1 = a.deptno1
and s.height = a.m_h
and s.deptno1 = d.deptno;
WHERE
다음에 서브쿼리가 오면 < 중첩 서브쿼리 > 라고 한다. 그냥 서브쿼리로 지칭하겠다.
서브쿼리의 결과가 1개라면 단일행 연산자를 이용, 2개이상이라면 다중행 연산자를 이용한다
서브쿼리가 FROM 절에 사용되면 동적으로 생성된 테이블인 것처럼 사용할 수 있다.
select
s.name, d.dname
from student s join department d
on s.deptno1 = d.deptno
and s.deptno1 = (
SELECT deptno1
FROM student
WHERE name ='Anthony Hopkins'
);
서브쿼리가 단하나의 결과를 출력하므로 단일행 연산자 =
를 이용한다
SELECT ENAME, SAL
FROM EMP
WHERE SAL < ANY (
SELECT SAL
FROM EMP
WHERE DEPTNO = 30
);
서브쿼리의 결과가 다중행이므로 다중행 연산자 < ANY
를 이용한다
SELECT
e.empno, e.name, e.deptno
FROM emp2 e join dept2 d
ON e.deptno = d.dcode
AND e.deptno in (
SELECT dcode
FROM dept2
WHERE area = 'Pohang Main Office'
);
서브쿼리의 결과에 따른 다중행 연산자 in
이용
SELECT
grade, name, weight
FROM student
WHERE (weight, grade) IN (
SELECT max(weight),grade
FROM student
GROUP BY grade
)
ORDER BY grade; -- () 와 ()를 연결해서 두개이상의 컬럼을 서브쿼리로 사용할수 있다