본문 바로가기

[오라클 레퍼런스 함수] FIRST_VALUE - 정렬된 집합에서 첫 번째 값 반환

by ㅇㅍㅍ 2023. 8. 5.
[오라클 레퍼런스 함수] FIRST_VALUE - 정렬된 집합에서 첫 번째 값 반환
728x90

FIRST_VALUE

 

구문

FIRST_VALUE 
  { (expr) [ {RESPECT | IGNORE} NULLS ]
  | (expr [ {RESPECT | IGNORE} NULLS ])
  }
  OVER (analytic_clause)

 

참고:

구문, 의미, 제한 사항 및 expr의 유효한 형식에 대한 정보는 "Analytic Functions"에 대한 내용을 참조하세요.

 

목적

FIRST_VALUE는 분석 함수로, 정렬된 값들의 집합에서 첫 번째 값을 반환합니다. 만약 집합의 첫 번째 값이 NULL인 경우, IGNORE NULLS를 지정하지 않으면 함수는 NULL을 반환합니다. 이 설정은 데이터 조밀화에 유용합니다.

 

노트: 이 두 가지 형식의 구문은 동일한 동작을 합니다. 상단 분기는 ANSI 형식으로, Oracle은 ANSI 호환성을 위해 이 형식을 권장합니다.

 

{RESPECT | IGNORE} NULLSexpr의 null 값이 계산에 포함되는지 아니면 제외되는지를 결정합니다. 기본값은 RESPECT NULLS입니다. 만약 IGNORE NULLS를 지정하면, FIRST_VALUE는 집합 내에서 첫 번째로 나오는 non-null 값이나 모든 값이 null인 경우 NULL을 반환합니다. 데이터 조밀화 예제는 "Using Partitioned Outer Joins: Examples"를 참조하십시오.

FIRST_VALUE나 다른 분석 함수를 expr로 사용하여 분석 함수를 중첩할 수 없습니다. 그러나 다른 내장 함수 표현식을 expr로 사용할 수 있습니다. expr의 유효한 형식에 대한 정보는 "About SQL Expressions"를 참조하십시오.

 

참고:

Oracle Database Globalization Support Guide의 부록 C는 FIRST_VALUE의 반환 값이 문자열 값인 경우 할당되는 정렬(collation) 결정 규칙에 대한 정보를 제공합니다.

 

예제

다음 예제는 부서 90에 속한 각 직원에 대해 최저 급여를 받는 직원의 이름을 선택합니다.

SELECT employee_id, last_name, salary, hire_date,
       FIRST_VALUE(last_name)
         OVER (ORDER BY salary ASC ROWS UNBOUNDED PRECEDING) AS fv
  FROM (SELECT * FROM employees
          WHERE department_id = 90
          ORDER BY hire_date);


EMPLOYEE_ID LAST_NAME                     SALARY HIRE_DATE FV
----------- ------------------------- ---------- --------- -------
        102 De Haan                        17000 13-JAN-01 De Haan
        101 Kochhar                        17000 21-SEP-05 De Haan
        100 King                           24000 17-JUN-03 De Haan

 

이 예제는 FIRST_VALUE 함수의 비결정적인 특성을 보여줍니다. Kochhar와 DeHaan은 동일한 급여를 받으므로 인접한 행에 위치합니다. 하지만 서브쿼리에 의해 반환된 행들이 hire_date로 정렬되어 있기 때문에 Kochhar가 먼저 나타납니다. 그러나 다음 예제와 같이 서브쿼리에 의해 반환된 행들이 hire_date를 내림차순으로 정렬된 경우, 함수는 다른 값이 반환됩니다.

SELECT employee_id, last_name, salary, hire_date,
       FIRST_VALUE(last_name)
         OVER (ORDER BY salary ASC ROWS UNBOUNDED PRECEDING) AS fv
  FROM (SELECT * FROM employees
          WHERE department_id = 90
          ORDER by hire_date DESC);

EMPLOYEE_ID LAST_NAME                     SALARY HIRE_DATE FV
----------- ------------------------- ---------- --------- -------
        101 Kochhar                        17000 21-SEP-05 Kochhar
        102 De Haan                        17000 13-JAN-01 Kochhar
        100 King                           24000 17-JUN-03 Kochhar

 

다음 두 가지 예제는 FIRST_VALUE 함수를 유일한 키(unique key)에 따라 정렬하여 결정적(deterministic)으로 만드는 방법을 보여줍니다. 함수 내에서 급여와 유일한 키인 employee_id 두 가지를 기준으로 정렬하면, 서브쿼리의 정렬 순서에 관계없이 항상 동일한 결과를 얻을 수 있습니다.

SELECT employee_id, last_name, salary, hire_date,
       FIRST_VALUE(last_name)
         OVER (ORDER BY salary ASC, employee_id ROWS UNBOUNDED PRECEDING) AS fv
  FROM (SELECT * FROM employees
          WHERE department_id = 90
          ORDER BY hire_date);
 
EMPLOYEE_ID LAST_NAME                     SALARY HIRE_DATE FV
----------- ------------------------- ---------- --------- -------
        101 Kochhar                        17000 21-SEP-05 Kochhar
        102 De Haan                        17000 13-JAN-01 Kochhar
        100 King                           24000 17-JUN-03 Kochhar
 
 
SELECT employee_id, last_name, salary, hire_date,
       FIRST_VALUE(last_name)
         OVER (ORDER BY salary ASC, employee_id ROWS UNBOUNDED PRECEDING) AS fv
   FROM (SELECT * FROM employees
           WHERE department_id = 90
           ORDER BY hire_date DESC);
 
EMPLOYEE_ID LAST_NAME                     SALARY HIRE_DATE FV
----------- ------------------------- ---------- --------- -------
        101 Kochhar                        17000 21-SEP-05 Kochhar
        102 De Haan                        17000 13-JAN-01 Kochhar
        100 King                           24000 17-JUN-03 Kochhar

 

다음 두 가지 예제는 FIRST_VALUE 함수를 논리적 오프셋(RANGE 대신 ROWS)을 사용할 때 결정적으로 만드는 것을 보여줍니다. ORDER BY 표현식에 중복이 발견되는 경우, FIRST_VALUEexpr의 가장 낮은 값이 됩니다.

SELECT employee_id, last_name, salary, hire_date,
       FIRST_VALUE(last_name)
         OVER (ORDER BY salary ASC RANGE UNBOUNDED PRECEDING) AS fv
  FROM (SELECT * FROM employees
          WHERE department_id = 90
          ORDER BY hire_date);
 
EMPLOYEE_ID LAST_NAME                     SALARY HIRE_DATE FV
----------- ------------------------- ---------- --------- -------
        102 De Haan                        17000 13-JAN-01 De Haan
        101 Kochhar                        17000 21-SEP-05 De Haan
        100 King                           24000 17-JUN-03 De Haan
 
 
SELECT employee_id, last_name, salary, hire_date,
       FIRST_VALUE(last_name)
         OVER (ORDER BY salary ASC RANGE UNBOUNDED PRECEDING) AS fv
  FROM (SELECT * FROM employees
          WHERE department_id = 90
          ORDER BY hire_date DESC);
 
EMPLOYEE_ID LAST_NAME                     SALARY HIRE_DATE FV
----------- ------------------------- ---------- --------- -------
        102 De Haan                        17000 13-JAN-01 De Haan
        101 Kochhar                        17000 21-SEP-05 De Haan
        100 King                           24000 17-JUN-03 De Haan

 


출처: 오라클 레퍼런스

원문 링크: Oracle FIRST_VALUE 함수 문서

 

반응형

댓글