SQL 질의

SELECT에 대해 자세히 설명합니다.

SELECT

SELECT 구문은 하나 이상의 테이블, 뷰로부터 원하는 데이터를 조회합니다.

SELECT의 세부 내용은 다음과 같습니다.

  • 문법

  • 특권

SELECT ANY TABLE 시스템 특권을 가진 사용자는 모든 테이블과 모든 뷰를 조회할 수 있습니다. 테이블 을 조회하기 위해서는 테이블을 사용자가 소유하고 있거나, 그 객체에 대해 SELECT 스키마 오브젝트 특권을 가지고 있어야 합니다.

뷰의 기반 테이블을 조회하기 위해서는 다음의 두 가지 조건을 동시에 만족해야 합니다.

  • 사용자가 뷰를 가지고 있거나 뷰에 대한 SELECT 스키마 오브젝트 특권이 있어야 합니다.

  • 뷰가 속한 스키마의 사용자가 뷰의 기반 테이블을 가지고 있거나 기반 테이블에 대해 SELECT 스키 마 오브젝트 특권을 가지고 있어야 합니다.

  • 구성요소

– select

구성요소
설명

with_clause

부질의를 정의하고 이름을 만듦

subquery

질의를 명시

for_update_clause

  • 질의 결과로 반환된 모든 ROW에 잠금을 설정하여 다른 사용자가 읽거나 갱신하지 못하도록 함

  • 설정된 잠금은 현재 트랜잭션이 종료될 때까지 계속 유지됨

  • for_update_clause는 부질의 안에는 포함할 수 없음

  • 둘 이상의 테이블 또는 뷰에 조인 질의를 수행하는 경우 for_update_clause는 모든 테이블 또는 뷰에 잠금을 설정

  • for_update_clause는 질의 결과의 ROW가 기반 테이블 내의 유일한 ROW로 결정될 수 없는 질의 문장에는 포함될 수 없음

  • 따라서, 다음과 같은 질의 문장 안에는 포함할 수 없음 – SELECT 절에 DISTINCT를 포함하는 문장 – 둘 이상의 테이블 또는 뷰에 대한 집합 또는 백 연산을 포함하는 문장 – GROUP BY 절을 포함하거나 SELECT 절에 집단 함수(Aggregate function)를 포함하는 문장

– with_clause

구성요소
설명

query_name

  • 부질의의 이름

  • 주 질의와 현재 부질의 다음에 정의되는 부질의에 query_name을 명시하여 사용

col_alias

subquery의 컬럼명을 재정의

subquery

질의를 명시

search_clause

행의 정렬방식을 지정

cycle_clause

순환 절에 대한 처리 방식을 지정

with_clause의 제약조건은 다음과 같습니다.

  • query_name으로 정의한 부질의 안에서 query_name을 참조하여 재귀 활용이 가능합니다.

  • 집합 연산자가 있는 복합 쿼리에서는 구성 요소 쿼리의 FROM 절 안에서만 query_name을 사용할 수 있습니다.

  • col_alias에 query_name과 중복되는 명칭을 사용할 수 없습니다.

– search_clause

구성요소
설명

depth first by

형제 행보다 자식 행이 먼저 반환되기를 원하는 경우 사용

breadth first by

자식 행보다 형제 행이 먼저 반환되기를 원하는 경우 사용

col_alias

  • 정렬하고자 하는 칼럼을 명시

  • 앞선 query_name에 대한 col_alias 목록 에 존재하는 칼럼을 지정해야 함

ASC

오름차순으로 정렬 기본값)

DESC

내림차순으로 정렬

NULL FIRST

  • NULL 값의 정렬 순서를 명시

  • NULLS FIRST는 내림차순 정렬의 디폴트로 사용됨

NULL LAST

  • NULL 값의 정렬 순서를 명시

  • NULLS LAST는 오름차순 정렬의 디폴트로 사용됨

ordering_column

  • query_name을 조회하는 쿼리에서 ordering_column을 ORDER BY 절에 사용함으로서 지정한 순서대로 행을 정렬할 수 있음

  • 앞선 query_name에 대한 col_alias 목록에 본 컬럼이 자동으로 추가됨

search_clause의 제약조건은 다음과 같습니다.

  • query_name에 대한 col_alias 목록에 존재하는 칼럼 명을 ordering_column 명으로 사용할 수 없습니다.

– cycle_clause

구성요소
설명

col_alias

  • 순환 여부를 판별할 칼럼을 명시

  • 앞선 query_name에 대한 col_alias 목록에 존재하는 칼럼을 지정해야 함

cycle_mark_col_alias

  • 순환 여부에 따른 특정 값을 저장하는 칼럼

  • 앞선 query_name에 대한 col_alias 목록에 본 칼럼이 자동으로 추가됨

TO cycle_value

  • 행에 대한 순환이 검출된 경우 cycle_mark_col_alias에 cycle_value값이 입력됨

  • 이 경우 해당 행에 대한 재귀는 중지되며 다른 비순환 행에 대해서는 계속해서 진행함

DEFAULT no_cycle_value

행에 대한 순환이 검출되지 않은 경우 cycle_mark_col_alias에 no_cycle_value값이 입력됨

cycle_clause의 제약조건은 다음과 같습니다.

  • cycle 절을 생략했으나 순환이 검출되는 경우 재귀 WITH 절은 에러를 출력합니다.

  • search 절과 함께 사용하는 경우 cycle_mark_col_alias명은 ordering_column명과 같지 않아야 합니다.

  • query_name에 대한 col_alias 목록에 존재하는 칼럼명을 cycle_mark_col_alias명으로 사용할 수 없습니다.

– subquery

구성요소
설명

hint

  • 힌트를 사용

  • 힌트는 일종의 지시문으로 최적화기의 특정 행동을 지시하거나 최적화기의 실행 계획을 변경

  • 자세한 내용은 “힌트”를 참고

set_quantifier

  • 질의 결과에 중복된 ROW의 허용, 비허용 여부를 지정

  • DISTINCT, UNIQUE, ALL을 지정할 수 있음 – DISTINCT, UNIQUE: 중복된 ROW를 제거 – ALL: 모든 ROW를 선택 (기본값)

select_list

  • 질의의 결과로 반환할 연산식을 명시

  • select_list에는 다음과 같은 제약조건이 있음

  • 만약 group_by_clause가 명시되어 있다면 select_list에서는 다음에 명시된 연산식의 조합만을 사용할 수 있음 – 상수 – 집합 함수 (aggregation function) – group_by_clause에 사용된 연산식으로 조합된 연산식

  • 조인 뷰에서 ROWID를 선택하면 마지막에 명시된 키 보조 테이블의 ROWID가 선택됨

  • 키 보조 테이블이 없다면, ROWID를 선택할 수 없음

  • 동일한 컬럼명을 가지는 2개 이상의 테이블 또는 뷰가 조인된 경우 특정 컬럼을 선택하기 위해서는 컬럼명이 테이블명 또는 별칭과 함께 명시되어야 함

FROM

질의의 대상으로 되는 하나 이상의 테이블, 뷰, 부질의를 명시

table_reference

질의할 테이블, 뷰, 인라인 뷰 등을 명시하고 조건 관계를 설정

where_clause

  • WHERE 절을 통하여 조건식을 만족하는 ROW만을 검색할 수 있으며, WHERE 절이 생략된 경우에는 질의의 대상이 되는 객체의 모든 ROW를 반환

  • 자세한 내용은 “조건식”을 참고

hierarchical_query_clause

  • 하나의 테이블 또는 조인된 둘 이상의 테이블의 ROW 간의 계층 관계를 정의하여 검색할 수 있음

  • 이러한 질의를 계층 질의라고 하며 START WITH … CONNECT BY 절을 이용하여 수행할 수 있음

  • CONNECT BY 절에는 다른 조건식에는 사용되지 않는 PRIOR 연산자가 포함됨

  • 계층 질의에서 정렬을 하고 싶다면 ORDER SIBLINGS BY 절을 사용

  • 자세한 내용은 “계층 질의”를 참고

group_by_clause

  • 질의 결과로 반환된 ROW를 하나 이상의 그룹으로 분리하기 위하여 GROUP BY 절을 이용

  • CUBE 또는 ROLLUP 확장을 사용할 경우에는 ROW를 모아놓은 그룹을 다시 모아 추가로 상위 그룹을 형성할 수 있음

  • 그룹으로 분리하기 위한 연산식은 하나 이상이 될 수 있으며, HAVING 절을 이용하여 원하는 그룹을 반환할 수 있음

  • 그룹으로 분리된 결과는 정렬되어 반환되지 않을 수도 있으므로, 이러한 경우에는 ORDER BY 절을 이용하여 최종 결과를 정렬할 수 있음

  • GROUP BY 절의 연산식으로 부질의, 대용량 객체형 데이터 타입의 컬럼을 사용할 수 없음

UNION (ALL)

  • 양쪽 질의 결과에서 중복된 ROW를 제거하고 새로운 하나의 질의 결과를 만듦

  • 예약어 ALL을 명시하면 중복된 ROW를 제거하지 않음

INTERSECT

양쪽 질의 결과에 동일하게 나타난 ROW를 모아 새로운 하나의 질의 결과를 만듦

MINUS

MINUS 예약어 이전에 명시된 질의 결과에서 이후에 명시된 질의 결과에 동일하게 나타나는 ROW를 제거해서 새로운 하나의 질의 결과를 만듦

EXCEPT

  • EXCEPT는 MINUS와 동일

  • EXCEPT 예약어 이전에 명시된 질의 결과에서 이후에 명시된 질의 결과에 동일하게 나타나는 ROW를 제거해서 새로운 하나의 질의 결과를 만듦

order_by_clause

  • 검색 결과의 ROW를 정렬하여 반환하기 위해 ORDER BY 절을 이용

  • 정렬 순서를 지정하기 위해 컬럼의 이름을 포함한 연산식이 올 수 있으며, 특정 컬럼의 위치 또는 컬럼의 별칭을 이용할 수 있음

  • 정렬 순서를 지정하기 위해 여러 가지 기준이 지정된 경우에는 먼저 지정된 기준에 따라 정렬을 수행하고 순서를 가리기 불가능한 경우에 다음 기준을 이용하게 됨

row_limiting_clause

검색 결과의 수를 제한하기 위해 OFFSET, FETCH, LIMIT 절을 이합니다.

– OFFSET 절: 전체 검색 결과 중 시작되는 ROW의 NUMBER를 지정할 수 있음

– FETCH 절: 몇 개의 ROW를 가져올 지 결정할 수 있음

– LIMIT 절: 쿼리의 수행 결과 중 원하는 ROW의 데이터만 가져올 수 있음

order_by_clause의 제약조건은 다음과 같습니다.

  • select_list에 예약어 DISTINCT가 사용되면 order_by_clause에서 select_list에 명시된 expr의 조합 만을 정렬의 키로 사용할 수 있습니다.

  • LOB, LONG 등과 같은 대용량 객체형 데이터 타입의 컬럼을 사용할 수 없습니다.

  • group_by_clause가 명시되어 있습니다면 아래의 4가지 expr만 order_by_clause에서 사용할 수 있습니다.

개수
가능한 expr

1

상수

2

집합 함수

3

분석 함수

4

group_by_clause에 사용된 expr의 조합

– select_list

구성요소
설명

애스터리스크(*)

FROM 절에 명시된 테이블과 뷰의 모든 컬럼을 선택

table., view.

명시된 테이블 또는 뷰의 모든 컬럼을 선택

expr

반환할 값을 계산하는 연산식

AS

별칭을 명시할 때 사용하는 예약어로 생략할 수 있음

col_alias

  • select_list에 명시된 연산식에 별칭을 설정

  • 동일한 질의에서는 order_by_clause에만 별칭을 사용할 수 있음

– table_reference

구성요소
설명

query_table_expr

조회할 스키마 객체를 명시

flashback_query_clause

테이블, 뷰 또는 부질의의 예전 데이터를 보기 위해 명시

tab_alias

테이블, 뷰 또는 부질의에 대한 별칭을 명시

join_clause

FROM 절에 명시된 테이블, 뷰, 부질의 간의 조인 관계를 명시

– query_table_expr

구성요소
설명

schema

  • 테이블이나 뷰가 속한 스키마를 명시

  • 생략하면 현재 사용자의 스키마로 인식됨

table

테이블의 이름을 명시

PARTITION (partition)

  • 특정 파티션의 이름을 명시

  • 테이블 전체가 아니라 명시된 파티션만 읽음

dblink

  • 데이터베이스 링크의 이름 전체 또는 부분을 명시함

  • 데이터베이스 링크를 명시할 때는 반드시 앞에 '@'를 붙여야 함

  • 링크는 다음과 같은 제약조건이 있음 – 원격 테이블에서는 Tibero에서 지원하지 않는 사용자 정의 타입 또는 REF 객체에 대한 질의를 할 수 없음 – 원격 테이블에서는 Tibero에서 지원하지 않는 ANYTYPE, ANYDATA 또는 ANYDATASET 타입의 컬럼에 대한 질의를 할 수 없음

view

뷰의 이름을 명시

sample_clause

테이블의 데이터를 무작위로 일부만 읽도록 함

subquery

부질의를 명시

collection_expression

  • 파이프라인드 테이블 함수(Pipelined Table Function)을 명시

  • 함수의 결과값을 테이블처럼 이용할 수 있게 함

  • 자세한 설명과 예제는 "Tibero tbPSM 안내서"의 "파이프라인드 테이블 함수"를 참조

xmltable

XMLTABLE 함수를 명시

– sample_clause

구성요소
설명

BLOCK

키워드를 명시하면 데이터 블록을 샘플링하고 명시하지 않으면 ROW를 샘플링

sample_percent

  • 샘플링할 ROW 또는 블록의 비율을 설정

  • 이 값은 .000001부터 100 사이의 값을 가짐

  • 100은 포함하지 않음

seed_value

  • 이 값이 같다면 다음 수행에서 동일한 샘플링 데이터를 취함

  • 명시하지 않으면 다음 수행할 때 다른 데이터를 얻게됨

  • 이 값은 0부터 4294967295 사이의 값을 가짐

– flashback_query_clause

구성요소
설명

expr

예전 시점을 나타내는 표현식

– SCN 또는 TIMESTAMP를 통해 특정 시점을 명시할 수 있음

– AS OF SCN을 사용하면 expr은 NUMBER 값이어야 함

– AS OF TIMESTAMP를 사용하면 expr은 TIMESTAMP 값이어야 함

flashback_query_clause는 다음과 같은 제약조건이 있습니다.

  • expr에 컬럼, 부질의를 사용할 수 없습니다.

  • with_clause에 정의된 부질의를 참조하려고 table_reference에 사용된 query_name에는 사용할 수 없습니다.

– pivot_clause

피봇은 테이블의 행을 열로 바꾼다. 동일 그룹에 속한 행에 집합함수를 적용해서 새로운 열의 값으로 사용합니다. 집합함수를 적용할 그룹을 결정하기 위한 GROUP BY 절은 사용하지 않습니다. pivot_clause 에 명시되지 않은 query_table_expr의 컬럼이 묵시적으로 GROUP BY 표현식으로 사용됩니다.

구성요소
설명

aggregate_function

  • 컬럼의 값을 생성할 집합 함수를 명시

  • alias를 명시하면 pivot_in_clause에서 생성된 컬럼명에 '_'와 alias를 추가로 붙여서 새로운 컬럼명을 생성

pivot_for_clause

피벗할 컬럼을 명시

pivot_in_clause

  • 피벗할 컬럼의 값을 명시

  • 명시된 개수만큼 새로운 컬럼이 만들어지고 값 별로 집합 함수를 적용해서 컬럼값을 계산

  • 명시되지 않은 값은 집합 함수에 적용되지 않음

  • alias를 사용하지 않으면 명시된 값을 컬럼명으로 사용

– unpivot_clause

UNPIVOT은 테이블의 열을 행으로 바꾼다. 한 로우의 여러 컬럼을 여러 로우의 동일 컬럼으로 변환합니다.

구성요소
설명

INCLUDE | EXCLUDE NULLS

  • INCLUDE NULLS는 NULL 값을 포함해서 로우를 생성

  • EXCLUDE NULLS이 명시되면 NULL 값으로 이루어진 로우를 생성하지 않음

  • 명시하지 않으면 EXCLUDE NULLS가 기본값

column

  • UNPIVOT된 쿼리 결과에 생성되는 측정값 컬럼의 컬럼명을 명시

  • UNPIVOT을 수행해서 보고자 하는 결과값을 측정값이라고 함

  • 동일한 타입이거나 최종 결과 타입으로 변환이 가능한 타입이어야 함

pivot_for_clause

  • UNPIVOT된 쿼리 결과에 생성되는 설명값 컬럼의 컬럼명을 명시

  • 이 컬럼에 채워지는 값은 측정값을 설명하는 용도로 사용

unpivot_in_clause

  • column의 값은 측정값 컬럼의 값이 됨

  • literal을 명시하면 설명값 컬럼의 값으로 사용됨

  • 명시하지 않으면 컬럼명을 값으로 사용

– join_clause

구성요소
설명

inner_join_clause

  • 내부 조인을 생성

  • 내부 조인 조건을 만족하는 ROW의 조인 결과만 조인됨

  • 내부(Inner)조인과 자연(Natural) 조인을 명시할 수 있음

  • 명시하지 않습니다면 내부 조인이 됨

outer_join_clause

  • 조인 조건에 맞는 모든 ROW와 한 쪽 테이블에서 조인 조건을 만족하지 않는 ROW가 선택됨

  • 조건을 만족하지 못한 ROW는 모든 컬럼이 NULL 값을 가지는 ROW와 조인 되어 선택됨

– inner_join_clause

구성요소
설명

INNER

  • 내부 조인을 명시

  • ON 절이나 USING 절에 의해 생성된 조인 조건을 만족하는 ROW만 조인

ON condition

조인 조건을 명시

USING column

  • 두 테이블에서 동일한 이름을 가지는 컬럼을 명시

  • 명시된 컬럼명을 가지는 양쪽 컬럼에 대해서 각각 동등 비교 조건을 모두 만족해야 한다는 조인 조건이 생성됨

  • 조인된 조건으로 사용된 컬럼은 조인된 ROW에 하나만 포함되고 테이블 이름이나 별칭과 함께 참조할 수 없음

NATURAL

  • 자연 조인을 명시

  • 두 테이블에서 동일한 이름을 갖는 컬럼은 각각 동등 비교 조건을 모두 만족해야 합니다는 조인 조건이 생성됨

  • 조인 조건으로 사용된 컬럼은 조인된 ROW에 하나만 포함되고 테이블 이름이나 별칭과 함께 참조할 수 없음

CROSS

  • 크로스 조인을 생성

  • 조인 되는 두 테이블의 모든 ROW가 조인됨

– outer_join_clause

옵션
설명

outer_join_type

외부 조인의 타입을 명시

ON condition

조인 조건을 명시

USING column

  • 두 테이블에서 동일한 이름을 가지는 컬럼을 명시

  • 명시된 컬럼명을 가지는 양 쪽 컬럼에 대해서 각각 동등 비교 조건을 모두 만족해야 한다는 조인 조건이 생성

  • 조인된 조인 조건으로 사용된 컬럼은 조인된 ROW에 하나만 포함되고 테이블 이름이나 별칭과 함께 참조할 수 없음

NATURAL

  • 자연 조인을 명시합니다. 두 테이블에서 동일한 이름을 갖는 컬럼은 각각 동등 비교 조건을 모두 만족해야 한다는 조인 조건이 생성됨

  • 조인 조건으로 사용된 컬럼은 조인된 ROW에 하나만 포함되고 테이블 이름이나 별칭과 함께 참조할 수 없음

– outer_join_type

구성요소
설명

LEFT

  • 왼쪽 외부 조인을 명시

  • 왼쪽 테이블의 모든 컬럼이 선택됨

RIGHT

  • 오른쪽 외부 조인을 명시

  • 오른쪽 테이블의 모든 컬럼이 선택됨

OUTER

생략할 수 있으며, 특별한 의미는 없음

– cross_join_clause

구성요소
설명

table_reference

조인할 테이블, 뷰, 인라인 뷰 등을 명시

– hierarchical_query_clause

구성요소
설명

CONNECT BY

ROW의 상하 관계를 정의하는 조건식을 명시

START WITH

계층 내의 루트 ROW를 지정하기 위한 조건식을 명시

condition

조건식을 명시

– group_by_clause

구성요소
설명

expr

그룹을 분리하기 위한 연산식을 명시

rollup_cube_clause

ROLLUP과 CUBE 연산을 명시

grouping_sets_clause

GROUPING SETS을 명시

HAVING condition

원하는 그룹만 반환하도록 하는 조건식을 명시

– grouping_sets_clause

구성요소
설명

GROUPING SETS

  • GROUPING SETS 뒤에 명시된 여러 개의 연산식을 바탕으로 선택된 ROW를 그룹으로 나누고, 각 그룹에 하나의 요약 정보 ROW를 반환

  • CUBE 또는 ROLLUP은 모든 연산식 조합에 대하여 그룹을 나누지만 GROUPING SETS를 사용하면 원하는 연산식만으로 그룹을 나누기 때문에 좀 더 효과적

  • 여러 개의 연산식에 대하여 GROUP BY를 수행한 결과에 UNION ALL을 한 것과 같은 결과를 갖기 때문에 중복된 ROW를 만들어 낼 수 있음

  • GROUPING SETS 뒤에 CUBE 또는 ROLLUP을 연산식 조합으로 명시 할 수 있는데 이런 경우에는 CUBE 또는 ROLLUP의 모든 연산식 조합을 직접 풀어 GROUPING SETS 뒤에 명시한 것과 같은 결과를 가짐

  • GROUPING SETS 뒤에 여러 개의 CUBE 또는 ROLLUP을 사용한 경우에는 각 연산식 조합의 cross product로 모든 연산식 조합을 계산하여 수행

– rollup_cube_clause

구성요소
설명

ROLLUP

  • 질의에서 선택된 ROW를 ROLLUP 뒤의 n개의 연산식 중 앞에서부터 n, n-1, n-2, … 0개의 연산식을 기반으로 하여 그룹으로 나누고, 각각의 그룹에 하나의 ROW를 반환

  • 예를 들어 SUM 집단 함수와 같이 사용할 경우는 중간 중간의 소계를 계산하기 위한 방법으로 이것을 사용할 수 있음

  • 이 경우 SUM은 가장 아래 레벨의 소계에서부터 전체 총계까지를 모두 계산함

CUBE

  • CUBE 뒤에 명시된 연산식의 가능한 모든 조합으로 선택된 ROW를 그룹으로 나누고, 각 그룹에 하나의 요약 정보 ROW를 반환

  • CUBE를 사용하여 교차표 값을 생성할 수 있음

  • 요약 정보는 그룹별 결과가 우선 출력되고, 그룹들의 요약 정보를 합친 결과가 나오는 순으로 출력되는데, 최종 결과 ROW는 전체의 요약 정보가 나오게 됨

  • 하지만, 반대로 전체 요약 정보부터 그룹들의 요약 정보, 그룹별 요약 정보 순으로 결과를 출력하고 싶은 경우에는 SUMMARY_FIRST_IN_GROUP_BY_CUBE 파라미터를 켜줌으로써 출력 순서를 변경할 수 있음

group_expr_list

리스트 연산식으로 구성된 묶음

– group_expr_list

구성요소
설명

expr_list

리스트 연산식

– order_by_clause

구성요소
설명

SIBLINGS

  • hierarchical_query_clause가 명시된 질의에 사용할 수 있음

  • order_by_clause는 계층 질의의 형제 노드 내에서 정렬 순서를 정의하게 됨

expr

정렬의 키로 사용되는 연산식

position

  • select_list에 명시된 expr의 위치를 지정

  • 해당 위치의 expr이 정렬에 사용됨

  • 정수 값을 사용해야 함

col_alias

컬럼의 별칭을 명시

ASC

오름차순으로 정렬 (기본값)

DESC

  • 내림차순으로 정렬

  • 이 부분을 생략하면 ASC로 인식

NULLS FIRST

  • NULL 값의 정렬 순서를 명시

  • NULLS FIRST는 내림차순 정렬의 디폴트로 사용됨

NULLS LAST

  • NULL 값의 정렬 순서를 명시

  • NULLS LAST는 오름차순 정렬의 디폴트로 사용됨

– for_update_clause

구성요소
설명

OF column

  • 일부 테이블 또는 뷰에만 잠금을 설정하고자 할 때에 사용

  • OF 예약어 뒤에 잠금을 설정하고자 하는 테이블의 컬럼을 나열

  • 이때, 컬럼의 별칭은 사용할 수 없음

schema

  • 스키마의 이름을 명시

  • 생략하면 현재 사용자의 스키마로 인식됨

table

테이블의 이름을 명시

view

뷰의 이름을 명시

NOWAIT

해당 ROW에 다른 사용자가 설정한 잠금이 있어도 해제될 때까지 기다리지 않음

WAIT

  • 해당 ROW에 다른 사용자가 설정한 잠금이 있는 경우 해제될 때까지 integer 만큼의 시간(초) 동안 시도

  • 지정되지 않으면 잠금이 해제될 때까지 기다림

SKIP LOCKED

해당 ROW에 다른 사용자가 설정한 잠금이 있는 경우 해당 ROW를 건너뛰고 다음 ROW로 넘어감

– row_limiting_clause

구성요소
설명

OFFSET

  • OFFSET 키워드를 사용하여 몇 개의 row를 건널 것인지 결정

  • offset은 숫자 혹은 숫자 값으로 표현되는 식이어야 함

  • 이 키워드를 지정하지 않으면 0으로 간주되어 첫 번째 row부터 결과 집합을 전달

ROW | ROWS

두 키워드는 의미적으로 명확성만 제공해줄 뿐 상호 교환하여 사용 가능

FETCH

  • 전달할 결과 집합의 row 수를 지정

  • 이 키워드를 지정하지 않으면 offset + 1 행부터 시작하여 모든 결과 집합을 전달

FIRST | NEXT

두 키워드는 의미적으로 명확성만 제공해줄 뿐 상호 교환하여 사용 가능

rowcount

  • rowcount는 숫자 혹은 숫자 값으로 표현되는 식이어야 함

  • rowcount가 offset + 1부터 시작해서 전달할 수 있는 모든 결과 집합의 row 수보다 클 경우 모든 가능한 결과 집합을 전달함

ROW | ROWS

두 키워드는 의미적으로 명확성만 제공해줄 뿐 상호 교환하여 사용 가능

ONLY

지정한 row 수만 정확하게 반환할 때 사용

LIMIT

LIMIT 키워드를 사용하여 쿼리의 수행 결과 중 원하는 행의 데이터를 가져올 수 있음

offset

  • 쿼리의 수행 결과 중 가져올 행의 시작점을 의미

  • 쿼리 수행 결과의 첫 번째 행의 offset 값은 0

limitnum

  • 지정한 offset을 포함하여 limitnum의 값만큼의 행을 가져옴

  • offset이 지정되어 있지 않다면 offset 값은 0으로 간주

– 집합 연산자

2개의 SELECT 문의 결과를 하나의 결과 집합으로 결합하는데 사용됩니다.

select_list에 대응되는 컬럼의 타입과 개수는 일치해야 합니다. 컬럼의 길이는 다를 수 있습니다. 참조되는 컬럼의 이름은 제일 좌측에 명시된 SELECT문의 select_list 절이 사용됩니다. SELECT 문이 집합 연산자에 의해 결합되는 경우 왼쪽에서 오른쪽 순서로 질의를 수행하게 됩니다. 자세한 내용은 “집합 연산자”를 참고합니다.

  • 예제

다음은 SELECT를 사용하는 예입니다.

다음은 비순환 구조에서 WITH 절을 재귀적으로 사용하는 예입니다.

다음은 순환 구조에서 WITH 절을 재귀적으로 사용하는 예입니다.

다음은 시간을 사용해서 FLASHBACK 쿼리를 수행한 예입니다.

다음은 TSN을 사용해서 FLASHBACK 쿼리를 수행한 예입니다. 동적뷰 V$TSN_TIME을 이용하면 TSN과 시간의 맵핑 정보를 알 수 있습니다.

다음은 PIVOT/UNPIVOT을 사용하는 예입니다.

조인

조인(Join)은 두 개 또는 여러 개의 테이블이나 뷰로부터 로우를 결합하는 질의입니다.

Tibero에서는 FROM절에 다수의 테이블이 있을 때 조인을 실행합니다.

질의의 SELECT 절에서 조인 테이블에 속하는 컬럼을 선택할 수 있습니다. 만일 조인될 테이블 중에 같은 이 름의 컬럼이 2개 이상이 있습니다면 테이블 이름을 함께 명시해 모호함을 없애야 합니다.

조인 조건

대부분의 조인 질의는 서로 다른 두 테이블의 컬럼을 비교하는 WHERE 절의 조건을 포함합니다. 이런 조건 을 조인 조건 (Join Condition)이라고 합니다.

조인을 실행하기 위해서 각 테이블의 로우를 하나씩 가져와 조인 조건이 TRUE로 결정되는 경우에만 결 합합니다. 조인 조건에 포함되는 컬럼이 반드시 SELECT절에 포함될 필요는 없습니다.

세 개 이상의 테이블을 조인할 때는 우선 두 개의 테이블과 그 두 테이블의 컬럼에 대응 되는 조인 조건을 이용해서 조인을 합니다. 그 후에, 그 두 테이블의 조인 결과의 컬럼과 세 번째 조인할 테이블의 컬럼에 해당 하는 조인 조건으로 조인하여 새로운 결과를 만든다.

Tibero는 이러한 과정을 하나의 결과가 나올 때까지 반복합니다. 최적화기(Optimizer)는 조인 조건과 테이블 에 대한 인덱스와 통계 정보를 사용해 테이블 간의 조인 순서를 정합니다. WHERE 절에 조인 조건 이외에 테이블에 하나에 대한 조건도 있을 수 있는데, 이러한 조건은 조인 질의로 반환되는 로우를 더욱 한정합니다.

카티션 프로덕트

조인 질의에서 테이블에 대한 조인 조건이 없을 경우 카티션 프로덕트(Cartesian Products)를 반환합니다. 카티션 프로덕트는 테이블의 한 로우가 다른 테이블의 모든 로우와 결합되는 것을 말합니다.

예를 들어 100개의 로우를 가지는 두 개의 테이블의 카티션 프로덕트는 100 * 100 = 10,000 로우입니다. 카 티션 프로덕트는 이렇게 결과가 너무 많기 때문에 거의 사용되지 않습니다. 특별히 카티션 프로덕트가 필요 한 경우가 아니라면, 항상 조인 조건을 포함해야 합니다. 만일 3개 이상의 테이블을 조인 할 때 그 중 2개의 테이블에 대한 조인 조건이 없었다면, 최적화기는 되도록 카티션 프로덕트가 생기지 않도록 조인순서를 정할 것입니다.

동등 조인

동등 조인(Equi Join)은 동등 연산자(=)로 구성된 조인 조건을 포함한 조인입니다. 동등 조인은 정해진 컬럼 에 대해 같은 값을 가지는 로우를 결합하여 결과로 반환합니다.

자체 조인

자체 조인(Self Join)은 하나의 테이블을 사용해서 자신에게 조인하는 것을 의미합니다. 동일한 하나의 테이 블이 FROM 절에 두 번 사용되기 때문에 별칭을 사용하여 컬럼을 구분합니다.

내부 조인

간단한 조인(Simple Join)이라고도 불리는 내부 조인(Inner Join)은 조인 조건을 만족하는 로우만 반환하 는 2개 이상의 테이블에 대한 조인입니다.

외부 조인

외부 조인(Outer Join)은 일반 조인을 확장한 결과를 출력합니다. 외부 조인은 조인 조건을 만족하는 로우뿐 만 아니라, 한 테이블의 어떤 로우에 대해 반대편 테이블의 모든 로우가 조인 조건을 만족하지 못하는 경 우에도 그 로우를 출력합니다.

외부 조인은 왼쪽 외부 조인, 오른쪽 외부 조인, 완전 외부 조인이 있습니다.

왼쪽 외부 조인(left outer join)

  • 테이블 A와 B를 조인하는 경우 조인 조건에 맞는 로우를 출력하고, A의 로우 중에 조인 조건에 맞는 B의 로우가 없는 경우에도 그 로우를 모두 출력합니다.

  • A의 로우 중 조인 조건을 만족하는 B의 로우가 없는 로우에 대해서는 조인의 출력에서 B 컬럼이 필요 한 부분에 모두 NULL을 출력합니다.

  • 왼쪽 외부 조인을 SQL 문장에 명시하려면 LEFT [OUTEROUTER] JOIN을 FROM 절에 명시하거나, WHERE절의 조인 조건에 있는 B의 모든 컬럼에 외부 조인 연산자 (+)를 명시합니다.

오른쪽 외부 조인(right outer join)

  • 테이블 A와 B를 조인하는 경우 조인 조건에 맞는 로우를 출력하고, B의 로우 중에 조인 조건에 맞는 A의 로우가 없는 경우에도 그 로우를 모두 출력합니다.

  • B의 로우 중 조인 조건을 만족하는 A의 로우가 없는 로우에 대해서는 조인의 출력에서 A 컬럼이 필요 한 부분에 모두 NULL을 출력합니다.

  • 오른쪽 외부 조인을 SQL 문장에 명시하려면 RIGHT [OUTEROUTEROUTEROUTER] JOIN을 FROM 절에 명시하거나, WHERE 절의 조인 조건에 있는 A의 모든 컬럼에 외부 조인 연산자 '(+)'를 명시합니다.

완전 외부 조인(full outer join)

  • 테이블 A와 B를 조인하는 경우 조인 조건에 맞는 로우를 출력하고, A의 로우 중에 조인 조건에 맞는 B 의 로우가 없는 경우에도 그 로우를 모두 출력하고, B의 로우 중에 조인 조건에 맞는 A의 로우가 없 는 경우에도 그 로우를 모두 출력합니다.

  • A의 로우 중 조인 조건을 만족하는 B의 로우가 없는 로우에 대해서는 조인의 출력에서 B 컬럼이 필요 한 부분에 모두 NULL을 출력합니다. B의 로우 중 조인 조건을 만족하는 A의 로우가 없는 로우에 대해 서는 조인의 출력에서 A 컬럼이 필요한 부분에 모두 NULL을 출력합니다.

  • 완전 외부 조인을 SQL 문장에 명시하려면 FULL [OUTEROUTEROUTEROUTER] JOIN을 FROM 절에 명시합니다. 여러 테이블 간의 외부 조인을 수행하는 질의에서 하나의 테이블은 오직 다른 하나의 테이블에 대해서만 NULL을 제공하는 테이블의 역할을 할 수 있습니다. 따라서, 테이블 A와 B에 대한 조건과 테이블 B와 C에 대 한 조건에서 모두 B의 컬럼 쪽에 (+) 연산자를 적용할 수는 없습니다.

외부 조인 연산자 (+)에는 FROM 절에 외부 조인을 명시할 경우에 다음과 같은 규칙과 제약 조건이 있습니다.

  • FROM 절에 조인이 있는 질의 블록에는 외부 조인을 사용할 수 없습니다.

  • (+) 연산자는 WHERE 절에만 올 수 있고, 테이블이나 뷰의 컬럼에만 적용할 수 있습니다.

  • 테이블 A와 B의 조인 조건이 여러 개 있을 경우에는 '(+)' 연산자를 모든 조건에 사용해야 합니다. 그렇지 않은 경우에는 아무런 경고나 에러 메시지 없이 일반 조인과 같이 취급합니다.

  • (+) 연산자를 외부 테이블과 내부 테이블에 모두 사용할 경우에는 일반 조인과 같이 취급합니다.

  • (+) 연산자는 컬럼에만 적용될 수 있고, 일반 연산식에는 적용될 수 없습니다. 단, 연산식 내의 컬럼에 '(+)' 연 산자를 적용할 수는 있습니다.

  • (+) 연산자를 포함하는 조건은 WHERE 절의 다른 조건과 OR 연산자를 통해 묶일 수 없습니다.

  • (+) 연산자가 적용된 컬럼을 IN 연산자를 이용해 비교하는 조건을 사용할 수 없습니다.

  • (+) 연산자가 적용된 컬럼을 부질의의 결과와 비교할 수 없습니다.

  • 테이블 A와 B의 외부 조인의 조건 중에 B의 컬럼을 상수와 비교하는 조건이 있습니다면, '(+)' 연산자를 B의 컬럼에 적용해야 합니다. 그렇지 않으면, 일반 조인과 같이 취급합니다.

안티 조인

안티 조인(Anti Join)은 프리디키트의 오른쪽 부분에 해당하는 로우가 없는 왼쪽 부분의 프리디키트에 해 당하는 로우를 반환합니다. 즉 프리디키트의 오른쪽 부분을 NOT IN의 부질의로 실행했을 때 일치하지 않는 로우를 반환합니다.

세미 조인

세미 조인(Semi Join)은 프리디키트의 오른쪽의 다수의 로우에 해당하는 왼쪽 부분의 로우를 중복 없이 처리하는 EXIST 부질의와 같은 로우를 반환합니다.

부질의가 WHERE 절의 OR로 연결되어 있으면 세미 조인과 안티 조인으로 변환되지 않습니다.

부질의

질의를 사용해서 어떤 문제를 해결하고자 할 때 단계를 나누어서 수행하면 좀 더 쉽게 문제를 풀 수 있는 경우가 있습니다.

예를 들어 Peter라는 사람이 속해있는 부서에서 일하는 사람 모두를 구하고자 할 때 먼저 Peter의 부서를 구하는 질의를 작성한 다음, 그 질의의 결과를 이용해 최종 답을 얻는 형태로 단계를 나눈 질의를 생각해 볼 수 있습니다. 이처럼 하나의 질의가 내부에 또 다른 질의를 포함하고 있을 경우 이 내부에 포함된 질의를 부 질의(Subquery)라고 합니다.

부질의는 질의가 사용된 위치에 따라 다음과 같이 두 가지 형태로 나눌 수 있습니다.

부질의 종류
설명

인라인 뷰

부질의가 부모 질의의 FROM 절에서 사용되었을 경우 이런 부질의를 보통 인라인(Inline) 뷰라고 부름

중첩된 부질의

부 질의가 부모 질의의 SELECT 리스트 또는 WHERE 절 등에서 사용되었을 경우 이런 부질의를 중첩된(Nested) 부질의 또는 부질이라고 부름

부질의는 다음과 같은 경우에 종종 사용됩니다.

  • INSERT 문을 통해 삽입할 로우의 값을 결정할 때

  • CREATE TABLE을 통해 테이블을 생성함과 동시에 테이블의 내용을 채울 때

  • CREATE VIEW 문을 통해 뷰가 질의하는 로우의 집합을 정의할 때

  • UPDATE 문에서 UPDATE할 값을 결정할 때

  • SELECT, UPDATE, DELETE 문에서 WHERE 절, HAVING 절, START WITH 절과 같은 조건을 명시할때

  • 테이블처럼 사용하고 싶은 로우의 집합을 정의할 때(SELECT의 FROM 절 또는 INSERT, UPDATE, DELETE에서 테이블을 명시할 수 있는 자리에 사용할 수 있습니다.)

circle-info

참고

부질의는 내부에 다른 부질의를 포함할 수 있으며, Tibero에서는 부질의가 다른 부질의를 포함할 수 있는 단계에 대해 제한을 두지 않습니다.

다음은 부질의와 컬럼 참조에 대한 설명입니다.

  • 인라인 뷰 인라인 뷰 내부에서는 부모 질의의 FROM 절에 명시된 다른 테이블 (또는 뷰)의 컬럼을 볼 수 없습니다.

  • 중첩된 부질의 인라인 뷰와 달리 중첩된 부질의는 부모 질의의 FROM 절에 명시된 테이블의 컬럼을 볼 수 있으며, 부 모 질의가 또 다른 질의의 중첩된 부질의일 경우 이 부모 질의의 FROM 절에 명시된 테이블의 컬럼 역 시 이 자식 부질의에서 볼 수 있습니다.

  • 서로 관련된(Correlated) 부질의 중첩된 부질의가 부모 질의의 테이블의 컬럼을 참조할 경우 이러한 부질의를 서로 관련된 부질의라고 합니다.

부질의의 컬럼을 참조할 때의 규칙은 다음과 같습니다.

  • 서로 관련된 부질의 내에서 부모 질의의 FROM 절의 테이블의 컬럼을 참조할 때 자신의 FROM 절의 테 이블의 컬럼과 동일한 이름을 가지고 있는 컬럼을 참조하고자 하는 경우에는 컬럼 이름 앞에 부모 질의 의 테이블 이름을 붙여 주어야 합니다.

  • 부모 질의의 컬럼을 참조할 때 위로 올라가는 단계에 대한 제한은 없습니다. 서로 관련된 부질의는 부모 질 의의 각각의 로우를 처리할 때 매번 일일이 별도로 수행됩니다.

  • 컬럼 이름에 대한 모호함이 발생하지 않는 한, 부질의에서 명시하는 (테이블 이름을 앞에 붙이지 않은) 컬럼 이름은 자신의 FROM 절의 테이블에서부터 시작해서 자신의 부모, 부모의 부모 순으로 컬럼 이름 을 찾아본다.

서로 관련된 부질의는 하위 단계에서 구하고자 하는 값이 상위 단계의 각각의 로우에 따라 별도로 결정되 어야 하는 경우에 사용됩니다.

다음과 같은 경우를 가정해 봅니다.

  • 자신의 부서의 평균 연봉보다 많은 연봉을 받는 사원의 리스트를 구하는 질의가 있습니다.

  • 이때, 하위 단계에서 계산하고자 하는 값은 각 사원에 대해서 그 사원이 근무하고 있는 부서의 평균 연 봉이 됩니다.

  • 또한, 상위 단계에서는 하위 단계에서 구한 평균 연봉을 현재 사원의 연봉과 비교하게 됩니다.

이러한 경우 평균 연봉을 각 사원에 대해 매번 구해야 하므로 이럴 경우 서로 관련된 부질의를 구사해서 문제를 해결할 수 있습니다.

다음은 스칼라(scalar) 부질의에 대한 설명입니다. 자세한 내용은 “부질의 연산식”을 참고합니다.

  • 어떤 부질의가 0개 또는 1개의 로우에서 1개의 컬럼만을 반환할 경우 이러한 부질의를 특별히 스칼라 부질의라고 부른다.

  • 스칼라 부질의는 연산식의 하나로 연산식 expr이 올 수 있는 자리에 마치 하나의 값처럼 간주되어 자유 로이 사용될 수 있습니다.

집합 연산자

집합 연산자는 두 개의 질의를 하나로 결합하는 데 사용됩니다. 집합 연산자에 의해 결합된 질의의 select_list에 명시된 연산식의 개수는 동일해야 하고 대응되는 연산식은 같은 데이터 타입 그룹에 속해야 합니다.

다음은 집합 연산자의 우선순위에 대한 설명입니다.

우선순위
집합 연산자
설명

1

INTERSECT

두 개의 질의 결과 양쪽 모두에 존재하는 로우를 결과로 반환합(A ∩ B)

2

UNION

두 개의 질의 결과에서 중복된 로우를 제거한 후 결과를 반환합(A ∪ B)

2

UNION ALL

두 개의 질의 결과에서 중복된 로우를 제거시키지 않고 모든 결과를 반환(A + B)

2

MINUS2

앞의 질의 결과에서 뒤의 질의 결과를 뺀 결과를 반환(A - B)

2

EXCEPT2

MINUS 집합 연산자와 동일하게 동작(A - B)

두 개 이상의 질의가 집합 연산자에 의해 결합되면, 다음과 같은 규칙이 적용됩니다.

  • 왼쪽에서 오른쪽 순서로 질의를 수행합니다.

  • 괄호를 사용하여 쿼리의 수행 순서를 조정할 수 있습니다.

집합 연산자는 다음과 같은 제약조건이 있습니다.

  • select_list가 BLOB, CLOB 타입의 연산식을 가질 경우 집합 연산자를 사용할 수 없습니다.

  • UNION, INTERSECT, MINUS, EXCEPT 연산자의 경우 LONG 타입의 컬럼이 허용되지 않습니다.

  • 먼저 명시된 질의의 select_list에 나오는 연산식에 별칭이 명시되어야만 order_by_clause에서 참조할 수 있습니다.

  • for_update_clause를 명시할 수 없습니다.

대응되는 연산식이 동일한 데이터 타입의 그룹이 아니면 암시적인 형 변환은 허용되지 않으며, 동일한 데 이터 타입의 그룹이면 다음과 같은 형 변환이 일어납니다.

  • 데이터 타입의 그룹이 숫자이면, 결과는 NUMBER 타입입니다.

  • 데이터 타입의 그룹이 문자이면, 다음의 규칙에 의해 결과의 데이터 타입이 결정됩니다.

    • 양쪽이 CHAR 타입이면, 결과는 CHAR 타입입니다.

    • 하나 또는 양쪽 모두 VARCHAR2 타입이면, 결과는 VARCHAR2 타입입니다.

계층 질의

계층 질의(Hierarchical Query)란 테이블에 포함된 로우 사이에 상하 계층 관계가 성립된 경우 그 상관 관 계에 따라 로우를 출력하는 질의입니다.

하나의 대상 테이블에 계층 관계는 하나 이상 정의할 수 있으며, 계층 질의는 하나의 테이블 또는 조인된 둘 이상의 테이블에 대해서도 가능합니다.

계층 질의를 위하여 SELECT 문장 내에 START WITH … CONNECT BY 절을 이용합니다.

  • START WITH 절은 계층 내의 루트 로우(root row)를 지정하기 위한 것입니다.

  • CONNECT BY 절은 로우 간의 상하 관계를 정의하기 위한 것입니다.

  • START WITH 절과 CONNECT BY 절에는 하나의 조건식이 포함되며, 단순 조건식 또는 복합 조건식일 수 있습니다. 자세한 내용은 “조건식”을 참고합니다.

계층 질의 연산자

PRIOR

CONNECT BY 절에는 다른 조건식에서는 포함되지 않는 특별한 연산자가 사용되는데, 로우 간의 상하 관 계를 나타내기 위한 PRIOR 연산자입니다.

PRIOR 연산자가 포함된 조건식은 다음과 같은 형식을 갖습니다.

PRIOR 쪽의 연산식의 결과 값을 갖는 로우가 반대 쪽의 연산식의 결과 값을 갖는 로우의 부모가 됩니다.

예를 들어 두 개의 컬럼 EMPNO와 MGRNO를 포함하는 테이블 EMP에 대하여 다음의 조건식을 이용하 여 계층 질의를 수행합니다면, 특정 (부모) 로우의 EMPNO 컬럼 값과 같은 MGRNO 컬럼 값을 갖는 모든 로우는, EMPNO 컬럼 값을 갖는 로우의 자식 로우가 됩니다.

다음의 테이블 EMP2 내의 로우 중에서 EMPNO 컬럼 값이 27인 (부모) 로우에 대하여 EMPNO 컬럼 값이 35, 42인 로우가 자식 로우가 됩니다. 두 컬럼 모두 MGRNO 컬럼 값이 27이기 때문입니다.

CONNECT BY 절의 조건식은 여러 단순 조건식이 연결된 복합 조건식이 될 수 있습니다. 하지만, PRIOR 연산 자를 포함한 단순 조건식은 반드시 하나만 포함되어야 하며, 0개 또는 2개 이상이 포함된 경우에는 에러 를 반환합니다. CONNECT BY 절의 조건식은 부질의를 포함할 수 없습니다.

CONNECT_BY_ROOT

계층 질의에서만 사용되는 또 다른 특수 연산자로 CONNECT_BY_ROOT 연산자가 있습니다.

CONNECT_BY_ROOT 연산자를 사용하면 데이터베이스는 루트 로우의 데이터를 이용하여 컬럼 값을 반 환합니다.

다음은 CONNECT_BY_ROOT 연산자를 사용한 예입니다.

계층 질의의 조건식

CONNECT BY 절

CONNECT BY 절의 조건식에는 등호 이외에 다른 비교 연산자를 사용할 수 있습니다. 하지만, 이때 상하 관 계가 순환적으로 정의될 수 있으며 무한 루프에 빠질 수 있습니다. 이러한 경우 Tibero에서는 에러를 반환하 고 실행을 중지합니다. 상하관계의 순환여부는 의사 컬럼인 CONNECT_BY_ISCYCLE 값으로 출력할 수 있습니다.

START WITH 절

START WITH 절은 계층 관계를 검색하기 위한 루트 로우에 대한 조건식을 포함합니다. 조건식에 따라 0 개 이상의 루트 로우로부터 시작될 수 있습니다. 만약 START WITH 절이 생략되면 대상 테이블 내의 모든 로우를 루트 로우로 하여 계층 관계를 검색합니다.

CONNECT BY 절과 WHERE 절의 혼합

하나의 SELECT 문 내에 CONNECT BY 절과 WHERE 절이 함께 사용된 경우 CONNECT BY 절의 조 건식을 먼저 적용합니다. 만약 SELECT 문이 조인 연산을 수행하며 WHERE 절 내에 조인 조건이 포함되 어 있습니다면, 조인 조건만 먼저 적용하여 조인을 수행한 후에 CONNECT BY 절의 조건식과 WHERE 절 내의 나머지 조건식을 차례로 적용합니다.

WHERE 절 내의 조건식은 CONNECT BY 절의 조건식에 의하여 로우 간에 상하 관계가 정해진 후에 적 용되므로, 특정 로우가 WHERE 절에 의하여 제거되더라도 그 로우의 하부 로우도 최종 결과에 포함될 수 있습니다.

ORDER SIBLINGS BY 절

계층 질의에 대해 일반적인 ORDER BY를 사용할 경우 상하 관계를 무시하고 정렬이 됩니다. 그러나 ORDER SIBLINGS BY 절을 사용할 경우엔 계층간의 상하 관계를 유지한 상태에서 같은 레벨에 있는 로우 들에 대해서만 정렬을 하므로 원하는 결과를 얻을 수 있습니다.

계층 질의의 실행 방식

계층 질의는 재귀적(Recursive)으로 실행됩니다.

먼저 하나의 루트 로우에 대해 모든 자식 로우를 검색합니다. 그 다음 각 자식 로우의 자식 로우를 다시 검색 합니다. 이러한 방법으로 다시는 자식 로우가 발견되지 않을 때까지 계속 진행합니다. 만약 무한 루프가 되면 에러를 반환합니다.

계층 질의의 결과를 출력하는 순서는 깊이 우선(Depth-First) 순서를 따릅니다.

다음의 그림은 테이블 EMP2의 계층 질의 결과로 구성된 계층 관계의 한 예이며, 원 안의 값은 EMPNO 컬 럼의 값입니다. 이때, 로우의 출력 순서는 12, 27, 35, 87, 42, 24, 54, 69입니다.

[그림 1] EMP2 테이블의 계층 관계

계층 트리의 각 로우는 레벨 값을 갖습니다. 루트 로우의 레벨 값은 1이며 자식 로우로 내려가면서 1씩 증가 합니다. 따라서, 위의 [그림 1]에서 EMPNO = 12인 로우는 레벨이 1이며, EMPNO = 27, 24인 로우는 레벨 이 2, EMPNO = 35, 42, 54, 69인 로우는 레벨이 3, EMPNO = 87인 로우는 레벨이 4입니다.

레벨 값은 의사 컬럼인 LEVEL 컬럼의 값으로 출력할 수 있습니다.

다음은 START WITH 절을 이용하지 않고 계층 질의를 실행하는 SELECT 문의 예입니다. 본 예제에서는 모 든 로우를 루트 로우로 하여 하부 로우를 출력합니다.

다음은 START WITH 절을 이용하여 계층 질의를 실행하는 SELECT 문의 예입니다. 본 예제에서는 EMPNO= 12인 조건식을 만족하는 하나의 루트 로우에 대해서만 하부 로우를 검색합니다.

다음은 WHERE 절을 포함하여 계층 질의를 실행하는 SELECT 문의 예입니다. 본 예제에서는 EMPNO = 27인 로우가 WHERE 절 때문에 제거되었으나, 그 하부 로우는 모두 그대로 출력됩니다.

다음은 LEVEL 컬럼을 포함하여 계층 질의를 실행하는 SELECT 문의 예입니다.

병렬 질의

병렬 질의란 하나의 SQL 문장을 여러 워킹 스레드를 사용하여 처리하는 것을 말합니다. 대용량 테이블을 스 캔할 때 여러 워킹 스레드가 테이블의 영역을 나눠서 처리하면 워킹 스레드 하나를 사용했을 때보다 빠르 게 작업을 실행할 수 있습니다.

병렬 질의는 OLTP(Online transaction processing) 환경 보다는 주로 데이터 웨어하우스(Data warehouse)와 같은 대용량 데이터를 다루는 환경에서 주로 사용됩니다. 다음은 병렬 질의를 사용하는 예입니다.

위의 예에서처럼 병렬 질의를 사용하기 위해서는 PARALLEL 힌트를 사용하면 됩니다. 'PARALLEL (4)'라 고 명시한 부분의 숫자 4는 병렬 질의 처리에서 사용할 워킹 스레드의 개수를 나타내며 보통 DOP(Degree of parallelism)라고 합니다. 즉 4개의 워킹 스레드를 사용해 해당 질의를 처리하도록 지시합니다.

이와 같이 병렬 질의 실행이 지시되면 Tibero 서버는 유휴 상태의 워킹 스레드를 사용자가 지정한 DOP 개 수만큼 확보하려 할 것입니다.

현재 사용할 수 있는 워킹 스레드가 힌트에 지정된 개수보다 부족합니다면 확보할 수 있는 워킹 스레드만을 사용해 병렬 질의를 실행합니다. 만약 유휴 상태의 워킹 스레드가 없어서, DOP가 1이 되면 병렬 질의는 진 행되지 않으며, 일반 질의처럼 처리됩니다. 이러한 상황을 별도의 에러 메시지를 통해 알려주지는 않습니다.

Tibero가 병렬 질의로 실행할 수 있는 연산은 다음과 같습니다.

  • TABLE FULL SCAN

  • INDEX FAST FULL SCAN

  • HASH JOIN

  • NESTED LOOP JOIN

  • MERGE JOIN

  • SET 연산

  • GROUP BY

  • ORDER BY

  • 집계 함수

Tibero는 병렬 질의를 실행하기 위해 실행 계획을 생성합니다.

다음은 병렬 질의를 실행하기 위해 실행 계획을 생성한 예입니다.

위의 예를 보면, PARALLEL 힌트를 사용한 병렬 질의의 실행 계획에 기존에는 없던 새로운 연산 노드가 추가가 된 것을 확인 할 수 있습니다. 이때 새로 추가된 노드는 병렬 질의 실행에 필요한 작업을 하게 됩니다.

PE RECV, PE SEND 노드가 추가된 경우에는 Tibero는 병렬 질의를 실행하기 위해 2-set 모델을 사용합니다. 이 경우 실제 사용하는 워킹 스레드의 개수는 DOP의 2배가 되며 2개의 set 중에서 한 곳의 워킹 스레 드는 consumer의 역할을, 다른 set의 워킹 스레드는 producer의 역할을 하게 됩니다. 이렇게 2-set 모델을 사용하는 이유는 두 연산 노드를 동시에 병렬로 실행하여 파이프라이닝(Pipelining) 효과를 보기 위해서입니다.

듀얼 테이블

듀얼 테이블(DUAL Table)은 VARCHAR(1) 타입의 하나의 컬럼 더미(Dummy)와 문자열 'X'를 포함하는 하 나의 로우를 포함하는 테이블입니다.

듀얼 테이블의 특성은 다음과 같습니다.

  • SYS 사용자뿐만 아니라 모든 사용자가 듀얼 테이블을 사용할 수 있습니다.

  • 삽입, 삭제, 갱신 연산이 허용되지 않으며, 테이블 자체를 변경하거나 제거할 수 없습니다.

  • 테이블의 내용과 상관없는 연산식의 계산에 사용할 수 있습니다.

  • 하나의 로우만을 포함하기 때문에 항상 연산식의 결과는 하나다.

다음은 듀얼 테이블을 사용하는 예입니다.

Last updated