[SQLD] 2과목 SQL 기본및 활용 - 3장 SQL 최적화 기본 원리 1절SQL 옵티마이져와 실행계획


1.옵티마이져

- 옵티마이저는 사용자가 질의한 SQL문에 대해 최적의 실행방법을 결정하는 역할을 함

- 최적의 실행방법을 실행계획이라고함.

- 다양한 실행 방법들 중 최적의 실행 방법을 결정하는 것이 바로 옵티마이져의 역할.

- 실행방법을 결정하는 방법에 따라 비용기반 옵티마이져와 규칙기반 옵티마이져로 나눌 수 있다.


가. 규칙기반 옵티마이져.

- 규칙기반 옵티마이져는 규칙(우선순위)을 가지고 실행계획을 생성함.

- 규칙기반 옵티마이져가 실행계획을 생성할 때 참조하는 정보에는 SQL문을 실행하기위해 이용가능한 인덱스의 종류, SQL 문에서 사용하는 연산자의 종류, SQL문에서 사용하는 객체의 종류 등이 있다. 이러한 정보에 따라 우선순위가 정해져 있고, 이 우선순위를 기반으로 실행계획을 생성한다.


 순위

엑세스 기법 

 1

Single row by rowid 

 2

Single row by cluster join 

 3

Single row by hash cluster key with unique or primary key 

 4

Single row by unique or primary key 

 5

Cluster join 

 6

Hash cluster key 

 7

Indexed cluster key 

 8

Composite index 

 9

Single cloumn index

 10

bounded range search on indexed columns

 11

unbounded range search on indexed columns

 12

sort merge join

 13

 MAX or MIN of indexed column

 14

ORDER BY on indexed column 

 15

FULL TABLE SCAN 

 


규칙1. Single row by rowid : 

ROWID를 통해서 테이블에서 하나의 행을 엑세스 하는 방법. 하나의 행을 엑세스하는 가장 빠른 방법.


규칙4. Single row by unique or primary key

유일 인덱스를 통해서 하나의 행을 엑세스 하는 방식. 인덱스를 먼져 엑세스 하고 인덱스에 존재하는 ROWID를 추출하여 테이블의 행을 엑세스한다.


규칙8. Composite index

복합인덱스에 동등 연산자 조건으로 검색하는 경우.

예를들어 A+B 칼럼으로 복합 인덱스가 새엇ㅇ되어 있을 때 WHERE A=1 AND B=1 형태로 검색하는 방식.

복합인덱스 사이의 우선순위 규칙은 인덱스 구성 칼럼의 개수가 더 많고 해당 인덱스의 모든 구성 칼럼에 대해 '='로 값이 주어질 수록 우선순위가 더 높다.

ex)A+B 와 A+B+C로 구성된 인덱스가 각각 존재할 때 a,b,c 칼럼에 대해 모두 =로 값이 주어진다면 A+B+C인덱스의 우선순위가 높으며, A,B 칼럼에만 = 로 값이 주어진다면 A+B+C 인덱스가 우선순위가 높다.


규칙9. Single Column Index

단일 칼럼 인덱스에 = 조건으로 검색하는 경우.


규칙 10. BOUNDED RANGE SEARCH ON INDEXED COLUMNS

인덱스가 생성되어 있는 칼럼에 양쪽 범위를 한정하는 형태로 검색하는 방식. BETWEEN, LIKE 등의 연산자가 있다.


규칙11. UNBOUNDED RANGE SEARCH ON INDEXED COLUMNS

인덱스가 생성되어 있는 칼럼에 한쪽 버뮈만 한정하는 형태로 검색하는 방식. >, >=,<,<= 등이 있다. 만약 A 칼럼에 인덱스가 생성되어 있고, A > '10' 또는 A <'20' 형태로 검색하는 방식.


규칙 15. FULL TABLE SCAN

전체 테이블을 엑세스 하면서 조건절에 주어진 조건을 만족하는 행만을 결과로 추출.


* 규칙기반 옵티마이저는 인덱스를 이용한 엑세스 방식이 전체 테이블 엑세스 방식보다 우선순위가 높다.

* 규칙기반 옵티마이저가 조인 순서를 결정할 때는 조인 칼럼 인덱스의 존재 유무가 중요한 판단의 기준이다.

1) 조인 칼럼에 대한 인덱스가 양쪽 테이블에 모두 존재한다면 설명한 규칙에 따라 우선순위가 높은 테이블을 선행테이블로 선택한다. 

2)한쪽 조인칼럼에만 인덱스가 존재하는 경우에는 인덱스가 없는 테이블을 선행 테이블로 선택해서 조인을 수행한다. 

3) 조인 칼럼에 모두 인덱스가 존재하지 않는 경우에는 FROM 절의 뒤에 나열된 테이블을 선행 테이블로 선택한다.

4) 만약 조인테이블의 우선순위가 동일할 경우 FROM 절에 나열된 테이블의 역순으로 선행 테이블을 선택한다.


* 규칙 옵티마이저의 조인 기법

양쪽 조인 칼럼에 모두 인덱스가 없는 경우 Sort Merge Join을 사용하고.

둘 중 하나라도 조인 칼럼에 인덱스가 있을 경우 일반적으로 NL Join을 사용한다.



나. 비용기반 옵티마이져

- 비용기반 옵티마이저는 SQL문을 처리하는데 필요한 비용이 가장 적은 실행계획을 선택하는 방식이다.

- 비용기반 옵티마이저는 비용을 예측하기 위해서 규칙기반 옵티마이저가 사용하지않는 테이블, 인덱스, 칼럼등의 다양한 객체 통계정보와 시스템 통계정보를 이용한다.

- 통계정보가 없는 경우 비용기반 옵티마이저는 정확한 비용예측이 불가능해서 비효율적인 실행계획을 생성할 수 있다.

- 비용기반 옵티마이저는 FULL TABLE SCAN이 INDEX SCAN 보다 유리하다고 판단할 경우 FULL TABLE SCAN을 수행한다.


* 비용기반 옵티마이저 구성

비용기만 옵티마이저는 질의 변환기, 대안 계획 생성기, 비용 예축기 등의 모듈로 구성되어있다.

1) 질의변환기

사용자가 작성한 SQL 문을 처리하기에 보다 용이한 형태로 변환하는 모듈.

2)대안 계획 생성기

돌일한 결과를 생성하는 다양한 대한 계획을 생성하는 모듈이다.

대안 계획은 연산의 적용 순서 변경, 연산 방법 변경, 조인 순서 변경 등을 통해서 생성된다.

( 많은 대안계획의 생성은 성능에 저하를 유발시킬 수 있으므로 대안 계획의 수를 제약하는 다양한 방법을 사용한다.)

3) 비용예측기

대안 계획 생성기에 의해서 생성된 대안 계획의 비용을 예측하는 모듈이다.

대안계획의 정확한 비용을 예측하기 위해서 연산의 중간 집합의 크기 및 결과 집합의 크기, 분포도 등의 예측이 정확해야 한다.


2. 실행계획

- SQL이 요구한 사항을 처리하기 위한 처리와 방법을 의미한다.

- 실행계획 생성한다는 것은 SQL을 어떤 순서로 처리할 지 결정하는 작업이다.

- 옵티마이저는 다양한 처리 방법들 중에서 가장 효율적인 방법을 찾아준다.

- 실행계획을 구성하는 요소에는 조인순서, 조인기법, 엑세스기법, 최적화정보, 연산 등이 있다.


1) 조인순서: 조인 작업을 수행할 때 참조하는 테이블의 순서이다.

2) 조인기법: 두 개의 테이블을 조인할 때 사용하는 방법으로 NL Join, Hash Join, Sort Merge Join 등이 있다.

3) 엑세스 기법: 인덱스를 이용하여 테이블을 엑세스하는 인덱스 스캔과 테이블 전체를 모두 읽으면서 조건을 만족하는 행을 찾는 풀 테이블 스캔이 있다.

4) 최적화정보: 옵티마이저가 실행계획의 각 단계마다 예상되는 비용을 표시한것.

cost: 상대적인 비용 정보

card: 주어진 조건을 만족한 결과 집합 혹은 조인 조건을 만족한 결과 집합 건 수

bytes: 결과집합이 차지하는 메모리 양을 바이트로 표시한 것.

이러한 정보들은 통계정보를 바탕으로 옵티마이저가 계산한 예상치이다.

5) 연산: 여러 가지 조작을 통해서 원하는 결과를 얻어내는 일련의 작업이다.

연산에는 조인 기법, 엑세스기법, 필터, 정렬, 집계, 뷰 등 다양한 종류가 존재한다.


3. SQL 처리 흐름도.

- SQL의 내부적인 처리절차를 시각적으로 표현한 도표이다.

- 실행계획을 시각화한 것이다.

조인순서는 TAB1 -> TAB2 일 때 TAB1을 Outer Table 또는 Driving Table 이라고 하고, TAB2를 Inner Table 또는 Lookup Table 이라고 한다.



[SQLD] 2과목 SQL 기본및 활용 - 1장 9절 JOIN


1. 조인의 개요

- 두 개 이상의 테이블 들을 연결 또는 결합하여 데이터를 출력하는 것을 JOIN이라고 한다.

- 일반적인 경우 행들은 PK나 FK값의 연관만으로 JOIN 성립이 가능하다.

- 선수라는 테이블과 팀이라는 테이블이 있는 경우 선수 테이블을 기준으로 필요한 데이터를 검색하고 이 데이터와 연관된 팀 테이블의 특정 행을 찾아오는 과정이 JOIN을 이용하여 데이터를 검색하는 과정으로 볼 수 있다.

- FROM 절에 여러개의 테이블을 나열하더라도 SQL에서 처리할 때는 단 두 개의 집합 간에만 조인이 일어난다. 

이때 테이블의 조인 순서는 옵티마이저에 의해 결정된다.

(FROM 절에 A, B, C 세 테이블이 나열되었 더라도 특정 2개의 테이블만 먼저 조인 처리되고, 나머지 두개의 테이블이 조인되어 처리된 새로운 데이터 집합과 남은 한 개의 테이블이 다음 차례로 조인된다.)


2. EQUI 조인

- EQUI 조인은 두 개의 테이블 간에 칼럼 값들이 서로 정확하게 일치하는 경우에 사용되는 방법으로

PK - FK 관계를 기반으로 한다. 

(일반적으로 테이블 설계시에 나타난 PK - FK의 관계를 이용하는 것이지 반드시 PK - FK 의 관계로만 EQUI JOIN이 발생하는 것은 아니다.)

- 이 기능은 계층형이나 망형 데이터베이스와 비교하여 관계형 데이터베이스의 큰 장점이다.

- JOIN 조건은 WHERE 절에 기술하게 되는데 " =  " 연산자를 사용해서 표현한다.

- 조인조건에 맞는 데이터만 출력하는 INNER JOIN에 참여하는 대상 테이블이 N개라고 했을 때 N개의 테이블로부터 필요한 데이터를 조회하기 위해 필요한 JOIN 조건은 대상 테이블의 개수에서 하나를 뺀 N-1개 이상 필요하다.

(EX. 나열된 테이블이 2개일 경우 1개이상 조건 필요하며, 3개일 경우 2개이상 조건이 필요함.)

SELECT 테이블1.칼럼명, 테이블2,칼럼명

FROM 테이블1, 테이블2

WHERE 테이블1.칼럼명 = 테이블2.칼럼명2;

* WHERE절에 JOIN 조건을 넣는다.


- ANSI/ISO SQL 표준방법으로 표기.

SELECT 테이블1.칼럼명, 테이블2.칼럼명 .. .. .

FRON 테이블1 INNER JOIN 테이블2

WHERE 테이블1.칼럼명1 = 테이블2.칼럼명2 ;


EX) 선수 테이블과 팀 테이블에서 선수 이름과 소속된 팀의 이름을 출력하시오.


A. 

SELECT PLAYER.PLAYERNAME, TEAM.TEAMNAME

FROM PLAYER, TEAM

WHERE PLAYER.TEAM_ID = TEAM.TEAM_ID


* ANSI/ISO SQL 표준방법 표기가능

SELECT PLAYER.PLAYERNAME, TEAM.TEAMNAME

FROM PLAYER INNER JOIN TEAM

ON PLAYER.TEAM_ID INNSER JOIN TEAM.TEAM_ID



- 테스트 가능한 EMP 테이블로 실행
각 사원별 부서이름을 출력하라.

1.

SELECT EMP.ENAME, DEPT.DNAME

FROM EMP, DEPT

WHERE EMP.DEPTNO = DEPT.DEPTNO ;


2.ANSI

SELECT EMP.ENAME, DEPT.DNAME

FROM EMP INNER JOIN DEPT

ON EMP.DEPTNO = DEPT.DEPTNO ;


ENAME   DNAME

---------- --------------

SMITH   RESEARCH

ALLEN   SALES

WARD   SALES

JONES   RESEARCH

MARTIN   SALES

BLAKE   SALES

CLARK   ACCOUNTING

SCOTT   RESEARCH

KING   ACCOUNTING

TURNER   SALES

ADAMS   RESEARCH

JAMES   SALES

FORD   RESEARCH

 

MILLER   ACCOUNTING

 



 가. 선수 - 팀 EQUI JOIN 사례

- 선수 테이블과 팀 테이블에서 K리그 소속 선수들의 이름,백넘버와 그 선수가 소속되어 있는 팀명 및 연고지를 알고싶은경우?

- 선수테이블의 소속코드를 기준으로 팀 테이블에 들어있는 데이터를 재배치 하여 결과를 얻게된다.

- 테이블 명을 앞에 쓸 경우 가독성이 떨어질 수 있으므로 ALIAS 를 주로 사용한다.


A. 

SELECT PLAYER.PLAYER_NAME, PLAYER.BACK_NO, TEAM.TEAM_NAME, TEAM.REGION_NAME

FROM PLAYER, TEAM

WHERE PLAYER.TEAM_ID = TEAM.TEAM_ID


A. ANSI 

SELECT PLAYER.PLAYER_NAME, PLAYER.BACK_NO, TEAM.TEAM_NAME, TEAM.REGION_NAME

FROM PLAYER INNER JOIN TEAM 

ON PLAYER.TEAM_ID = TEAM.TEAM_ID


A. ALIAS 적용

SELECT P.PLAYER_NAME, P.BACK_NO, T.TEAM_NAME, T.REGION_NAME

FROM PLAYER P, TEAM T

WHERE P.TEAM_ID = T.TEAM_ID


SELECT P.PLAYER_NAME, P.BACK_NO, T.TEAM_NAME, T.REGION_NAME

FROM PLAYER P INNER JOIN TEAM T

WHERE P.TEAM_ID = T.TEAM_ID


나. 선수 - 팀 WHERE 절 검색 조건 사례

- WHERE절에 JOIN 조건 이외이 검색 조건에 대한 제한 조건을 덧붙여 사용할 수 있다.

- EQUI JOIN의 최소한의 연관 관계를 위해서 테이블 개수 - 1 개의 JOIN 조건을 WHERE 절에 명시하고, 부수적인 제한조건을 논리 연산자를 통하여 추가로 입력하는것이 가능하다.

- JOIN 조건을 기술 할 때 만약 테이블에 대한 ALIAS를 적용해서 SQL문장을 작성했을 경우, WHERE절과 SELECT 절에는 테이블명이 아닌 테이블에 대한 ALIAS를 사용해야한다.  => 에러발생


SELECT PLAYER.PLAYER_NAME, P.BACK_NO, T.TEAM_NAME, T.REGION_NAME

FROM PLAYER P , TEAM T

WHERE P.TEAM_ID = T.TEAM_ID

AND PLAYER.POSITION='GK'
ORDER BY PLAYER.BACK_NO;


Q. 위에 수행한 쿼리에 포지션이 골키퍼인 선수들에 대한 데이터반 백넘버순으로 출력.


A.

SELECT PLAYER.PLAYER_NAME, PLAYER.BACK_NO, TEAM.TEAM_NAME, TEAM.REGION_NAME

FROM PLAYER, TEAM

WHERE PLAYER.TEAM_ID = TEAM.TEAM_ID

AND PLAYER.POSITION='GK'
ORDER BY PLAYER.BACK_NO;



다. 팀 - 구장 EQUI 조인 사례


Q. 팀 테이블과 구장 테이블의 관계를 이용하여 소속팀이 가지고있는 전용구장의 정보를 팀 정보와 함께 출력


SELECT T.REGEION_NAME, T.TEAM_NAME, T.STADIUM_ID, S.STADIUM_NAME, S.SEATCOUNT

FROM TEAM T, STADIUM S

WHERE T.STADIUM_ID = S.STADIUM_ID;


* 중복이 되지 않는 컬럼에 대해서는 테이블 명과 ALIAS를 쓰지 않아도 되며, 같은 이름을 가진 중복 칼럼의 경우 테이블명이나 ALIAS 가 필수이다.


SELECT REGEION_NAME, TEAM_NAME, T.STADIUM_ID, STADIUM_NAME, SEATCOUNT

FROM TEAM T, STADIUM S

WHERE T.STADIUM_ID = S.STADIUM_ID;

=> 가능.

3. NON EQUI
-  NON EQUI 조인은 두 테이블간에 칼럼 들이 서로 정확하게 일치하지 않는 경우에 사용된다.
" = " 연산자가 아닌 BEETWEEN, >, >=, <, <= 연산자 등을 사용하여 조인한다.
- 두개의 테이블이 PK - FK로 연관관계를 가지거나 논리적으로 같은값이 존재하는 경우 EQUI 조인을 수행하지만, 두 개의 테이블 간에 칼럼 값들이 서로 정확하게 일치하지 않는 경우에 EQUI 조인을 사용할 수 없다. 이런 경우에 Non EQUI JOIN을 시도할 수 있으나 데이터 모델에 따라서 NON EQUI JOIN이 불가능한 경우도 있다.
(PLAYER 모델에서는 할 수 없음.)

- NON EQUI JOIN의 대략적인 형태

SELECT 테이블1.칼럼1, 테이블2.칼럼2 . .. ...

FROM 테이블1, 테이블2

WHERE 테이블1.칼럼명1 BETWEEN 테이블2.칼럼명1 AND 테이블2.칼럼명2

* BETWEEN a AND b 조건은 Non EQUI JOIN의 한 사례이다.


ex) EMP 테이블과 SAL테이블을 이용하여 어떤사원의 급여가 어느 등급에 속하는지 알고 싶다는 요구사항에 대한 non equi join

A.

SELECT E.ENAME, E.JOB, E.SAL, S.GRADE

FROM EMP E, SALGRADE S

WHERE E.SAL BETWEEN S.LOSAL AND S.HISAL ;




4. 3개 이상 테이블 조인

- 선수들별로 홈그라운드 경기장이 어디인지 출력하고 싶다고 했을 때, 선수테이블과 운동장 테이블은 서로 관련이 없으므로 중간에 팀 테이블이라는 서로 연관관계가 있는 테이블을 추가해서 세 개의 테이블을 JOIN 해야만 원하는 데이터를 얻을 수 있다.


EX)

SELECT P.PLAYER_NAME, P.POSITION, T.REGION_NAME, T.TEA_NAME, S.STADIUM_NAME

FROM PLAYER P, TEAM T, STADIUM S

WHERE P.TEAM_ID = T.TEAM_ID

      AND T.STADIUM_ID = S.STADIUM_ID

ORDER BY 선수명;



* INNER JOIN 

SELECT P.PLAYER_NAME, P.POSITION, T.REGION_NAME, T.TEA_NAME, S.STADIUM_NAME

FROM PLAYER P INNER JOIN  TEAM T ON P.TEAM_ID = T.TEAM_ID

            INNER JOIN STADIUM S ON  T.STADIUM_ID = S.STADIUM_ID

ORDER BY 선수명;


 

 


[SQLD] 2과목 SQL 기본및 활용 - 1장 8절 ORDER BY 절


1. ORDER BY 절

- SQL 문장으로 조회된 테이블을 다양한 목적에 맞게 특정 칼럼을 기준으로 정렬하여 출력하는데 사용한다.

- ORDER BY 절에 칼럼명 대신에 SELECT 절에서 사용한 ALIAS명이나 칼럼 순서를 나타내는 정수도 사용한다.


SELECT 칼럼명

FROM  테이블명

[WHERE 조건식]

[GROUP BY 칼럼이나 표현식]

[HAVING 그룹조건식]

[ORDER BY 칼럼이나 표현식 [ASC 또는 DESC] ;

 


* ASC : 오름차순정렬( DEFAULT)

* DESC : 내림차순 정렬


* ORDER BY 절 사용 특징.

- 기본적인 정렬 순서는 오름차순(ASC) 이다.

- 숫자형 데이터 타입은 오르차순으로 정렬했을 때 가장 작은 값부터 출력된다.

- 날짜형 데이터 타입은 오름차순으로 정렬했을 때 날짜 값이 가장 빠른 값이 먼저 출력된다.

(2015/01/01 -> 2015/01/02 ->2015/01/03 ....)

- 오라클은 NULL값을 사용할 경우 가장 큰 값으로 간주하며, SQL server는 가장 작은값으로 간주한다.

- ORDER BY 절에 칼럼의 순서로 명시할 수 있다

(EX. ORDER BY 3 DESC, 2,1)



EX1.) 컬럼기준 정렬

SELECT DEPTNO, AVG(SAL)

FROM EMP

GROUP BY DEPTNO

HAVING MAX(SAL) >=3000

ORDER BY DEPTNO ;


결과
DEPTNO   AVG(SAL)

---------- ----------

10         2916.66667

20         2175


* 정렬안한 결과

DEPTNO   AVG(SAL)

---------- ----------

20          2175

10          2916.66667


EX2.) ALIAS 기준 정렬

SELECT DEPTNO DEP_AS, AVG(SAL)

FROM EMP

GROUP BY DEPTNO

HAVING MAX(SAL) >=3000

ORDER BY DEP_AS;


결과
DEPTNO   AVG(SAL)

---------- ----------

10         2916.66667

20         2175


EX3) NULL 값에 대한 정렬
SELECT ENANE, COMM
FROM EMP
ORDER BY COMM;

* 오라클에서는 NULL 값을 가장 큰 값으로 취급한다.

* SQL Server에서는 NULL 값을 가장 작은 값으로 취급.

ENAME COMM

---------- ----------

TURNER     0

ALLEN   300

WARD   500

MARTIN 1400

SCOTT

KING

ADAMS

JAMES

FORD

MILLER

BLAKE

JONES

GOODBOY

CLARK


EX4)여러가지 컬럼을 기준으로 정렬

연봉이 높은 순서대로, 연봉이 같은경우 커미션이 높은 순서대로 정렬


SELECT ENAME, SAL, NVL(COMM,0) NVL_COMM

FROM EMP

ORDER BY SAL, NVL_COMM;




EX5) 칼럼 순서로 정렬.

SELECT ENAME, SAL, NVL(COMM,0) NVL_COMM

FROM EMP

ORDER BY 2,3,1;



 예제. DEPT 테이블 정보를 부서명, 지역별, 부서번호 내림차순으로 정렬하여 출력.


EX1) 칼럼명사용.

SELECT DNAME, LOC, DEPTNO

FROM DEPT

ORDER BY DNAME, LOC, DEPTNO;


EX2) 칼럼명 + ALIAS 사용 

SELECT DNAME, LOC LOC_AS, DEPTNO

FROM DEPT

ORDER BY DNAME, LOC_AS, DEPTNO;


EX3) 칼럼순서번호 + ALIAS 사용

SELECT DNAME, LOC LOC_AS, DEPTNO

FROM DEPT

ORDER BY 1, LOC_AS, 3;


-결과는 모두 같다.
 


 



2. SELECT 문장 실행 순서.

- GROUP BY 절과 ORDER BY 절이 같이 사용될 때 SELECT 문장은 6개의 절로 구성된다.


1. SELECT

2. FROM

3. WHERE

4. GROUP BY

5. HAVING

6. ORDER BY


=> 문장 실행 순서.(옵티마이저가 SYNTAX 및 SEMANTIC 에러를 점검하는 순서) 

1. 발췌대상 테이블 참조.( FROM )

2. 발췌대상 데이터가 아닌것은 제거 ( WHERE)

3. 행들을 소그룹화 (GROUP BY)

4. 그룹핑된 값의 조건에 맞는 것만을 출력 (HAVING)

5. 데이터값을 출력 및 계산 (SELECT)

6. 데이터를 정렬(ORDER BY)


* ORDER BY절에는 SELECT 목록에 없는 문자형 항목이 포함될 수 있다.

단, SELET DISTINCT를 지정하거나 SQL 문장에 GROUP BY 절이 있거나 또는 SELECT문에 UNION 연산자가 있으면 열정의가 SELECT 목록에 표시되어야 한다.

(관계형 DB에서 데이터를 메모리로 올릴 때 행단위로 모든 컬럼을 가져오게되므로 SELECT절에서는 일부만 선택하더라도 ORDER BY 절에서 메모리에 올라온 다른 컬럼데이터를 사용할 수 있다.)


ex) SELECT 절에 없는 EMP 칼럼을 ORDER BY 절에 사용.

SELECT EMPNO, ENAME

FROM EMP

ORDER BY MGR ;


     EMPNO ENAME

---------- ----------

      7902 FORD

      7788 SCOTT

      7900 JAMES

      7499 ALLEN

      7521 WARD

      7844 TURNER

      7654 MARTIN

      7934 MILLER

      7876 ADAMS

      7698 BLAKE

      7566 JONES

      7782 CLARK

      7369 GOODBOY

      7839 KING





ex) 인라인 뷰에 정의된 SELECT 칼럼을 메인쿼리에서 사용.

SELECT EMPNO

FROM (SELECT EMPNO, ENAME FROM EMP ORDER BY MGR);


     EMPNO

----------

      7902

      7788

      7900

      7499

      7521

      7844

      7654

      7934

      7876

      7698

      7566

      7782

      7369

      7839



ex) 인라인 뷰에 미정의된 SELECT 칼럼을 메인쿼리에서 사용.

SELECT MGR

FROM (SELECT EMPNO, ENAME FROM EMP ORDER BY MGR;)


결과

ERROR at line 1:

ORA-00904: "MGR": invalid identifier

=> MGR이 인라인뷰를 통해 조회되지않음.


- 서브쿼리절에서 선택되지 않은 컬럼들은 계속 유지가 되는것이 아니라 서브쿼리 범위를 벗어나면 더이상 하용할 수 없다.



-GROUP BY 절에서 그룹핑 기준을 정의하게 되면 데이터베이스는 일반적인 SELECT 문장처럼 FROM 절에 정의된 테이블 구조를 그대로 가지고 가는 것이 아니라 GROUP BY 절의 그룹핑 기준에 사용된 칼럼과 집계 함수에

사용될 수 있는 숫자형 데이터 칼럼들의 집합을 새로 만든다.

GROUP BY 절을 사용하게 되면 그룹핑 기준에 사용된 칼럼과 집계함수에 사용될 수 있는 숫자형 데이터 컬럼들의 집합을 새로 마드는데 개별 데이터는 필요 없으므로 저장되지 않는다. GROUP BY 이후 수행 절인 SELECT 절이나 ORDER BY 절에서 개별 데이터를 사용할 경우 에러가 발생한다.

* SELECT 절에서는 그룹핑 기준과 숫자 형식 칼럼의 집계함수를 사용할 수 있지만 그룹핑 기준 외의 문자 형식 칼럼은 정할 수 없다.


- GROUP BY 절 사용 시 SELECT 절에 일반 칼럼을 사용

SELECT JOB, SAL

FROM EMP

GROUP BY JOB

HAVING COUNT(*) > 0

ORDER BY SAL;

 


ERROR at line 1:

ORA-00979: not a GROUP BY expression

 


=> 에러발생.


- GROUP BY 절 사용시 ORDER BY 절에 일반 칼럼을 사용해본다.

SELECT JOB

FROM EMP

GROUP BY JOB

HAVING COUNT(*) > 0

ORDER BY SAL;


ORA-00979: not a GROUP BY expression

 

=> 에러발생


- GROUP BY 절 사용시 ORDER BY 절에 집계 칼럼 사용.

SELECT JOB

FROM EMP

GROUP BY JOB

HAVING COUNT(*) > 0

ORDER BY MAX(EMPNO), MAX(MGR), SUM(SAL), COUNT(DEPTNO), MAX(HIREDATE);



JOB

---------

singer

people

actor

MANAGER

PRESIDENT

SALESMAN

ANALYST

CLERK

 



3. TOP N 쿼리

- ROWNUM

오라클에서 우선순위가 높은 N개의 로우를 추출하기 위해 ORDER BY 절과 WHERE 절의 ROWNUM조건을 같이 사용하는 경우가 있는데 이 두조건으로는 원하는 값을 얻을 수 없다.

오라클의 경우 정렬이 완료된 후 데이터의 일부가 출력되는 것이 아니라 데이터의 일부가 추출된 후 데이터에 대한 정렬작업을 수행한다.


예제. 사원테이블에서 급여가 높은 3명만 내림차순으로 출력


SELECT ENAME, SAL

FROM EMP

WHERE ROWNUM < = 3

ORDER BY SAL DESC;


ENAME   SAL

---------- ----------

ALLEN 1600

WARD 1250

 

GOODBOY   800

=> 해당 결과는 급여에 대한 오름차순 정렬이 아니라 무작위로 추출된 3명에 대해 급여를 내림차순으로 정렬한 결과이므로 원하는 결과가 출력된것이아니다.

( WHERE 절이 ORDER BY 절보다 먼저 수행 되기 때문이다.)



A. 정답. 인라인 뷰를 통해 데이터 정렬을 먼저 수행 후 메인쿼리에서 ROWNUM 사용.


SELECT  ENAME, SAL

FROM (SELECT ENAME, SAL FROM EMP ORDER BY SAL DESC)

WHERE ROWNUM < = 3 ;


ENAME   SAL

---------- ----------

KING 5000

SCOTT 3000

 

FORD 3000


* 인라인뷰를 사용하여 추출하고자 하는 집합을 정렬한 후 ROWNUM을 적용시킴으로써 결과에 참여하는 순서와 추출된는 로우 순서를 일치 시킴으로써 TOP N 쿼리의 결과를 만들었다.


- TOP

반면에, SQL server는 조건을 사용하게 되면 별도의 처리 없이 관련 ORDER BY 절의 데이터 정렬 후 원하는 일부 데이터만 쉽게 출력할 수 있다.


 TOP (EXPRESSION) [PERCENT] [WITH TIES]

 


* TOP 절을 사용해서 결과 집합으로 반환되는 행의 수를 제한할 수 있다. 

- WITH TIES 옵션은 ORDER BY 절의 조건 기준으로 TOP N 의 마지막 행으로 표시되는 추가 행의 데이터가 같을경우 N+ 동일정렬 순서 데이터를 추가 반환하도록 지정하는 옵션이다.


EX) 사원테이블에서 급여가 높은 2명을 내림차순으로 출력.

SELECT TOP(2) ENAME, SAL

FROM EMP

ORDER BY SAL DESC;


ENAME   SAL

---------- ----------

KING 5000

SCOTT 3000

 



EX2) 사원테이블에서 급여가 높은 2명을 내림차순으로 출력하는데, 같은 급여를 받는 사원이 있으면 같이 출력

SELECT TOP(2) WITH TIES ENAME, SAL

FROM EMP

ORDER BY SAL DESC;


ENAME   SAL

---------- ----------

KING 5000

SCOTT 3000

 

FORD 3000