db

Subquery특징

C/H 2006. 9. 22. 02:59

서브쿼리는 쿼리 안에 또 쿼리가 들어가있는 형태이다.
from 절과 where절에 사용이 가능하다.
MAIN QUERY가 실행되기 이전 실행이 된다.

SUBQUERY의 사용목적

1. 데이터의 재구성
- 뷰를 사용하는 것과 마찬가지로 원하는 칼럼, 원하는 데이터 부분만을 불러올때 사용한다.
- 여기에는 하나의 테이블을 쪼개서 필요한 부분만을 불러올 수 도 있으며(게시판에서 자주 사용하는 방법)
- 테이블간 조인을 하는 쿼리를 subquery로 사용하여 데이터를 수집할 수도 있다.

2. 하나이상의 명확하지 않은 조건절의 사용시 유용하다.
- 조건절이 명확하여 where name='kkaok' 이렇게만 되면 너무도 행복하다. 하지만 조건절에 "작년 오늘부터 현재의 오늘"이라든지 "다른 테이블에 kkaok이라는 이름으로 된 데이터와 같은..." 이런식의 조건이 붙으면 쿼리문을 몇번을 나눠서 사용하든지 해야 한다. 이런 경우는 자주 볼 수 있는 형태로 subquery를 사용하면 쉽게 구현이 가능하다.

SUBQUERY의 유형

1. from 절에서 사용
orlacle
[code sql]select * from (select idx from kqna where rownum<=5 order by idx desc) where rownum <=2 order by idx desc;[/code]
# mssql
[code sql]select top 2 * from (select top 5 idx from kqna order by idx desc) order by idx desc [/code]
위의 쿼리문은 kqna 테이블에서 자신이 원하는 데이터를 서브쿼리문을 통해 필요한 부분만 선택해서 가상의 테이블처럼 구성하는 형태이다.

subquery는 "("와 ")"안에 삽입이 되면 하나의 쿼리문에 여러개의 subquery도 가능하며 실행 순서는 subquery가 먼저 실행이 되고 그다음에 main 쿼리문이 실행이 된다.

oracle
[code sql]select * from (select idx from kqna order by idx desc) where rownum <=2;[/code]
위의 예제는 단순히 kqna라는 테이블의 정렬을 바꾸는 것으로 실제 사용될 그런 예제는 아니다. 이러한 방법이 oracle에서는 가능하지만 mssql에서는 불가능한다.
mssql
[code sql]select top 2 * from (select idx from kqna order by idx desc)[/code]
error!
[Microsoft][ODBC SQL Server Driver][SQL Server]Top을 함께 지정하지 않는 한 뷰, 인라인 함수, 파생 테이블, 하위 쿼리에서 ORDER BY 절을 사용할 수 없습니다.
mssql에서는 subquery 안에 정렬을 하고 싶다면 반드시 top으로 수량을 명시해야만 한다.
oracle
[code sql]select a.idx from(select idx from kqna where rownum<=5 order by idx desc)a, kfaq b where a.idx=b.seq order by a.idx desc;[/code]
mssql
[code sql]select a.idx from (select top 5 idx from kqna order by idx desc) a inner join kfaq b on a.idx=b.seq order by a.idx desc[/code]

위의 예제는 subquery와 일반 테이블의 join 형태이다. 이외에 subquery와 subquery 간에 join도 가능하다.
* mysql은 현재 subquery는 지원하지 않는다. 따라서 table간 join만을 이용해야한다.

2. where 절에서 사용

subquery의 결과값이 하나일때는 subquery 앞에 붙는 조건은 기존의 모든것을 사용할 수 있다. 하지만 둘 이상의 결과 값일때는 =,!=,<,<=,>,>= 는 사용할 수 없다.

oracle
[code sql]select name from kjsp where name = (select name from kqna where (rownum <= 1) and (name = '까오기')) order by idx desc;[/code]
mssql
[code sql]select name from kjsp where name = (select top 1 name from kqna where (name = '까오기')) order by idx desc;[/code]
하나이상일때는 error가 발생한다.
oracle
[code sql]select name from kjsp where name = (select name from kqna where (name = '까오기')) order by idx desc;[/code]
mssql
[code sql]select name from kjsp where name = (select name from kqna where (name = '까오기')) order by idx desc;[/code]
위의 경우는 다음처럼 해결할 수 있다.
oracle
[code sql]select name from kjsp where name in (select name from kqna where (name = '까오기')) order by idx desc;[/code]
mssql
[code sql]select name from kjsp where name in (select name from kqna where (name = '까오기')) order by idx desc;[/code]


출처 : 까오기네
반응형

'db' 카테고리의 다른 글

마이그레이션 이런된장  (0) 2010.10.28
DBMS에 따른 날짜포맷 변환  (0) 2008.11.10
게시판 write시 자동증가 컬럼의 비효율성 극복  (0) 2006.10.20
DBMS의 SQL 비교  (0) 2006.10.19
limit, rownum, top  (0) 2006.09.22