본문 바로가기

[오라클 레퍼런스 함수] LAST_VALUE - 정렬된 값 집합 내 마지막 값 반환

by ㅇㅍㅍ 2023. 8. 9.
[오라클 레퍼런스 함수] LAST_VALUE - 정렬된 값 집합 내 마지막 값 반환
728x90

 

 

 

LAST_VALUE

 

구문

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

 

참고:

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

 

목적

LAST_VALUE는 데이터 밀도화(densification)에 유용한 분석 함수입니다. 이는 정렬된 값 집합에서 마지막 값을 반환합니다.

 

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

 

{RESPECT | IGNORE} NULLSexpr의 null 값이 계산에 포함될지 아니면 제외될지를 결정합니다. 기본값은 RESPECT NULLS입니다. 집합 내에서 마지막 값이 null인 경우, 함수는 NULL을 반환합니다. 그러나 IGNORE NULLS를 지정하면, LAST_VALUE는 집합 내에서 마지막으로 null이 아닌 값을 반환하며, 모든 값이 null인 경우에는 NULL을 반환합니다. 데이터 덴시피케이션(data densification)의 예제는 "Using Partitioned Outer Joins: Examples"를 참조하세요.

LAST_VALUE나 다른 analytic 함수를 expr에 사용하여 analytic 함수를 중첩할 수 없습니다. 그러나 expr에는 다른 내장 함수 표현식을 사용할 수 있습니다. expr의 유효한 형식에 대한 정보는 "About SQL Expressions"을(를) 참조하세요.

analytic_clausewindowing_clause를 생략하면 기본값은 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW로 설정됩니다. 이 기본값은 때로 예상하지 못한 값을 반환할 수 있습니다. 왜냐하면 창의 마지막 값은 창의 아래에 있으며 고정되지 않기 때문입니다. 현재 행이 변경될 때마다 계속 변경됩니다. 예상된 결과를 얻으려면 windowing_clauseRANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING으로 지정하거나, 대체로 windowing_clauseRANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING으로 지정할 수 있습니다.

 

참고:

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

 

예제

다음 예제는 각 행에 대해 가장 낮은 급여를 받는 직원의 고용일을 반환합니다.

SELECT employee_id, last_name, salary, hire_date,
       LAST_VALUE(hire_date)
         OVER (ORDER BY salary DESC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED
               FOLLOWING) AS lv
  FROM (SELECT * FROM employees
          WHERE department_id = 90
          ORDER BY hire_date);

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

 

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

SELECT employee_id, last_name, salary, hire_date,
       LAST_VALUE(hire_date)
         OVER (ORDER BY salary DESC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED
               FOLLOWING) AS lv
  FROM (SELECT * FROM employees
          WHERE department_id = 90
          ORDER BY hire_date DESC);

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

 

다음 두 예제는 LAST_VALUE 함수를 결정론적으로 만드는 방법을 보여줍니다. 함수 내에서 급여와 고유 키인 employee_id 둘 다를 기준으로 정렬함으로써 서브쿼리의 정렬 순서와 상관없이 동일한 결과를 보장할 수 있습니다.

SELECT employee_id, last_name, salary, hire_date,
       LAST_VALUE(hire_date)
         OVER (ORDER BY salary DESC, employee_id ROWS BETWEEN UNBOUNDED PRECEDING
               AND UNBOUNDED FOLLOWING) AS lv
  FROM (SELECT * FROM employees
          WHERE department_id = 90
          ORDER BY hire_date);

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


SELECT employee_id, last_name, salary, hire_date,
       LAST_VALUE(hire_date)
         OVER (ORDER BY salary DESC, employee_id ROWS BETWEEN UNBOUNDED PRECEDING
               AND UNBOUNDED FOLLOWING) AS lv
  FROM (SELECT * FROM employees
          WHERE department_id = 90
          ORDER BY hire_date DESC);

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

 

다음 두 예제는 마지막 값 함수(LAST_VALUE)가 논리적 오프셋(RANGEROWS)을 사용할 때 결정론적임을 보여줍니다. ORDER BY 식에 중복이 있는 경우, LAST_VALUEexpr의 가장 높은 값입니다.

SELECT employee_id, last_name, salary, hire_date,
       LAST_VALUE(hire_date)
         OVER (ORDER BY salary DESC RANGE BETWEEN UNBOUNDED PRECEDING AND
               UNBOUNDED FOLLOWING) AS lv
  FROM (SELECT * FROM employees
          WHERE department_id = 90
          ORDER BY hire_date);

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


SELECT employee_id, last_name, salary, hire_date,
       LAST_VALUE(hire_date)
         OVER (ORDER BY salary DESC RANGE BETWEEN UNBOUNDED PRECEDING AND
               UNBOUNDED FOLLOWING) AS lv
  FROM (SELECT * FROM employees
          WHERE department_id = 90
          ORDER BY hire_date DESC);

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

 


출처: 오라클 레퍼런스

원문 링크: Oracle LAST_VALUE 함수 문서

 

반응형

댓글