이 내용은 2011년 6월 현재 SQL2011(코드명 Denali) Beta를 기준으로 작성 되었으며
SQL2011(코드명 Denali) 공식버전(RTM) 발표까지 꾸준히 업데이트 예정입니다.
아울러, 현재 Beta버전이지만 강좌를 따라해
보시는데 아무 문제 없으실거에요. 도움 되시길
바랍니다.
==================================================================================================
안녕하세요. 이스트럭 강동운입니다.
이번에는 서브 쿼리에 대해서 살펴보도록 하겠습니다.
서브 쿼리는 크게 총 4가지 형태로 나뉠 수 있습니다.
1. 단일 행 서브쿼리
2. 다중 행 서브쿼리
3. 인라인 뷰
4. 상관관계 서브쿼리
일단 단일 행을 살펴보기 전에 단일 행을 반환하는 함수 몇 가지에 대해서 소개해볼까 합니다.
USE pubs GO SELECT COUNT(*) AS Count1
--// 총 행 수 , COUNT(price) AS Count2
--// 총 행 수를 구하되,price 가 null 이 아닌 것만 , SUM(Price) AS SumPrice
--//price 의 총 합(null 은 무시됨) , AVG(Price) AS AvgPrice
--//price의 평균 값(null 은 무시됨) , MIN(Price) AS MinPrice
--//price의 최소 값(null 은 무시됨) , MAX(Price) AS MaxPrice
--//price의 최대 값(null 은 무시됨) from TITLES
Price 의 값 중 null인 데이터가 두개가 존재하기 때문에,
COUNT(price)는 16을 반환하게 됩니다. |
TOP
Keyword
--//하나만 가져오기 위해서.. SELECT TOP (1) title_id, title FROM titles
--//10 %의 데이터를 가져오는 방법! SELECT TOP 10 PERCENT title_id, title FROM titles
--//이런식으로 괄호안에 단일행 반환으로 이용할 수도 있음. SELECT TOP (SELECT 10) title_id, title FROM titles
|
1. 단일 행 서브쿼리
단일 행 서브쿼리는 위의 TOP 예제처럼 괄호 안의 쿼리에서 한 개의 행을 반환하는 쿼리를 이용해 서브쿼리를 작성하는 방법입니다.
예제를 통해서 살펴보도록 하겠습니다.
예) price가 가장 싼 titles의 판매정보(sales) 데이터 추출 하기
select * from sales where title_id = (select top 1 title_id from titles where price > 0 order by price)
|
예) 첫번째인 title_id의 판매정보(sales) 데이터 추출하기
select * from sales where title_id = (select MIN(title_id) from titles)
|
그렇다면 한 개 말고 두개 이상의 행일 때는 어떻게 될까요?
set language '한국어’ select * from sales where title_id = (select title_id from titles)
--//서브쿼리에 여러행 반환하도록 수정 Msg 512,
Level 16, State 1, Line 1 하위 쿼리에서 값을 둘 이상 반환했습니다. 하위 쿼리 앞에 =, !=,
<, <=, >, >= 등이 오거나 하위 쿼리가 하나의 식으로 사용된 경우에는 여러 값을 반환할 수 없습니다. |
그렇다면, 반환되는 행이 두 개 이상일 경우에는 어떻게 해야 할까요?
2. 다중 행 서브쿼리
반환되는 행이 여러행인 경우에는 위의 에러 처럼 = 를 사용할 수 없습니다. 바로 in 연산자를 사용해야 합니다.
select * from sales where title_id in (select title_id from titles)
|
In 말고 not
in도 가능하겠죠~!
Price가 가장 높은 상위 10
percent의 책을 제외한 판매 정보!
select * from sales where title_id not in (select top 10 percent title_id from titles order by price desc)
|
3. 인라인 뷰
인라인 뷰는 FROM 절 뒤에 테이블 명이 나와야 하지만 서브쿼리가 하나의 가상의 테이블을 반환 함으로 써 사용되는 경우를 말합니다.
바로 예제를 통해서 알아보도록 하겠습니다.
예1) 한번 이상 판매된 책들의 titles 정보의 데이터 반환
select * from ( select title_id , COUNT(*) as TotalCount from sales group by title_id ) as a inner join titles as b on a.title_id = b.title_id
|
예2) 3번 이상 판매된 책들의 titles 정보의 데이터 반환
select * from ( select title_id , COUNT(*) as TotalCount from sales group by title_id having COUNT(*) >=3 ) as a inner join titles as b on a.title_id = b.title_id
|
이처럼 from 절 뒤에 나오는 괄호의 데이터가 다중 행이 되면서 하나의 가상의 테이블이 되는 경우를 인라인 뷰라고 합니다. 정말 많은 곳에 사용되고, 필수로 익혀야 할 스킬 입니다.
4. 상관관계 서브쿼리
상관관계 서브쿼리는 말이 참 어렵습니다. 이 것은 번역 때문에 그렇게 된 것 같습니다. 참으로 안타깝습니다.
예제를 보시면 좀 더 빠르게 이해가 될 수 있을 것 입니다.
판매 정보 테이블에서 최근에 주문된 10건의 데이터를 title과 함께 출력하라
SELECT TOP 10 stor_id , ord_num , ord_date , title_id , (select top 1 title from titles where title_id = a.title_id) as titles FROM sales a order by ord_date desc
|
판매정보 테이블에는 title_id만 있고 title는 없습니다. 따라서 이 정보를 가져오기 위해서는 titles에 조인을 해서 데이터를 가져와야 합니다. 위의 예제의 상관관계 서브쿼리는 바깥쪽의 sales 테이블에 대해서 10개의 행을 가지고 오고, 각 title를 가져오기 위해 괄호안에 있는 쿼리를 10번을 수행하게 됩니다. 이때 두개의 쿼리가 상관이 있다고 하여 상관관계 서브쿼리라 부릅니다. 사실 이는 조인으로도 풀 수 있습니다.
SELECT TOP 10 a.stor_id , a.ord_num , a.ord_date , a.title_id , b.title FROM sales a inner join titles b on a.title_id = b.title_id order by ord_date desc |
결과는 위의 쿼리와 똑같습니다.
서브 쿼리는 SQL
Server 에선 없어서 안될 아주 중요한 요소 입니다. 다양하게 많이 쓰이고 있고, 제가 소개한 방법을 기본으로 삼아 응용과 활용한다면, 보다 다양한 형태로 쿼리를 작성하실 수 있습니다.
항상 무슨 일이든 기본이 제일 중요한 것 같습니다. ^^
감사합니다.
[출처] SQLER.COM http://www.sqler.com/390154
SQL2011(코드명 Denali) 시리즈 강좌
리스트
[SQL2011강좌] 1. 코드명
Denali 설치 방법
[SQL2011강좌] 2.
SSMS 접속 및 간단한 쿼리 실행
[SQL2011강좌] 3. SQL Server 의 MDF, LDF 그리고 데이터베이스 생성하기
[SQL2011강좌] 4. DDL 1탄: 테이블 생성
[SQL2011강좌] 5. DDL 2탄: 쿼리를 이용한 테이블 컬럼 추가
및 삭제
[SQL2011강좌] 6. Primary
key와 Unique 제약조건
[SQL2011강좌]
7. DML 1탄 INSERT
[SQL2011강좌]
8. DML 1탄 INSERT(identity 속성)
[SQL2011강좌] 9. Sequence
[SQL2011강좌] 10. pubs, northwind Database 예제 설치
[SQL2011강좌] 11. SELECT(단일 테이블)
[SQL2011강좌] 12. SELECT(JOIN)
[SQL2011강좌] 13. UPDATE, DELETE
절
[SQL2011강좌] 14. DISTINCT,
UNION, UNION ALL 키워드
[SQL2011강좌] 15. ORDER BY, GROUP BY, HAVING
[SQL2011강좌] 16. SubQuery(서브쿼리)
[SQL2011강좌] 17. 뷰에 대한 이해 및 생성, 수정,
삭제
[SQL2011강좌] 18. 저장 프로시저에 대한
이해, 생성, 수정, 삭제
[SQL2011강좌] 19.
인덱스에 대한 이해
[SQL2011강좌] 20.
클러스터드 인덱스와 넌 클러스터드 인덱스
[SQL2011강좌] 21. 트랜잭션에 대한이해
[SQL2011강좌] 22. 트랜잭션의 격리수준 4가지
[SQL2011강좌] 23. 잠금에 대한 이해
[SQL2011강좌] 24. 백업과 복구에 대한 이해(풀백업, 차등백업, 트랜잭션 로그 백업)
[SQL2011강좌] 25. 백업과 복구 전략
[SQL2011강좌] 26. 커서란?
SQL2011(코드명 Denali) 시리즈
동영상 강좌 리스트
[SQL2011 동영상 강좌] 1. 코드명 Denali 설치 방법
[SQL2011 동영상 강좌] 2.
SSMS 접속 및 간단한 쿼리 실행
[SQL2011 동영상 강좌] 3. SQL Server 의 MDF, LDF 그리고 데이터베이스
생성하기
[SQL2011 동영상 강좌] 4. DDL 1탄: 테이블 생성
[SQL2011 동영상 강좌] 5.
DDL 2탄: 쿼리를 이용한 테이블 컬럼 추가 및 삭제
[SQL2011 동영상 강좌] 6. Primary key와 Unique
제약조건
[SQL2011 동영상 강좌] 7. DML 1탄 INSERT
[SQL2011 동영상 강좌] 8.
DML 1탄 INSERT(identity 속성)
[SQL2011 동영상 강좌] 9. Sequence
[SQL2011 동영상 강좌] 10.
pubs, northwind Database 예제 설치
[SQL2011 동영상 강좌] 11. SELECT(단일 테이블)
[SQL2011 동영상 강좌] 12.
SELECT(JOIN)
[SQL2011 동영상 강좌] 13. UPDATE, DELETE 절
[SQL2011 동영상 강좌] 14.
DISTINCT, UNION, UNION ALL 키워드
[SQL2011 동영상 강좌] 15. ORDER BY, GROUP BY,
HAVING
[SQL2011 동영상 강좌] 16. SubQuery(서브쿼리)
[SQL2011 동영상 강좌] 17.
뷰에 대한 이해 및 생성, 수정, 삭제
[SQL2011 동영상 강좌] 18. 저장 프로시저에 대한 이해, 생성, 수정, 삭제
[SQL2011 동영상 강좌] 19.
인덱스에 대한 이해
[SQL2011 동영상 강좌] 20. 클러스터드 인덱스와 넌 클러스터드 인덱스
[SQL2011 동영상 강좌] 21.
트랜잭션에 대한이해
[SQL2011 동영상 강좌] 22. 트랜잭션의 격리수준 4가지
[SQL2011 동영상 강좌] 23.
잠금에 대한 이해
[SQL2011 동영상 강좌] 24. 백업과 복구에 대한 이해(풀백업, 차등백업, 트랜잭션 로그
백업)
[SQL2011
동영상 강좌] 25. 백업과 복구 전략
[SQL2011 동영상 강좌] 26. 커서란?
'프로그램&DB > MS-SQL' 카테고리의 다른 글
[MS-SQL2011강좌] 18. 저장 프로시저에 대한 이해, 생성, 수정, 삭제 by 강동운님 (0) | 2011.08.23 |
---|---|
[MS-SQL2011강좌] 17. 뷰에 대한 이해 및 생성, 수정, 삭제 by 강동운님 (0) | 2011.08.23 |
[MS-SQL2011강좌] 15. ORDER BY, GROUP BY, HAVING by 강동운님 (0) | 2011.08.23 |
[MS-SQL2011강좌] 14. DISTINCT, UNION, UNION ALL 키워드 by 강동운님 (0) | 2011.08.23 |
[MS-SQL2011강좌] 13. UPDATE, DELETE 절 by 강동운님 (0) | 2011.08.23 |