LAST_VALUE
構文
関連項目:
構文、セマンティクス、制限事項、およびexprの書式の詳細は、「分析ファンクション」を参照してください。
目的
LAST_VALUEはデータの稠密化に役立つ分析ファンクションです。これは、順序付けられた値の集合にある最後の値を戻します。
ノート:
この構文の2つの書式は、同じ動作になります。上のブランチはANSI形式です。ANSIとの互換性を維持するために、こちらを使用することをお薦めします。
{RESPECT | IGNORE} NULLSは、exprのNULL値を計算に含めるか除外するかを指定します。デフォルトはRESPECT NULLSです。集合内の最後の値がNULLの場合、IGNORE NULLSを指定していないかぎり、ファンクションはNULLを戻します。IGNORE NULLSを指定すると、LAST_VALUEは集合内の最後のNULLではない値を戻します。すべての値がNULLの場合はNULLを戻します。データの稠密化の例は、「パーティション化された外部結合の使用方法: 例」を参照してください。
exprには、LAST_VALUEまたは他の分析ファンクションを使用して分析ファンクションをネストできません。ただし、他の組込みファンクション式をexprで使用できます。exprの書式の詳細は、「SQL式」を参照してください。
analytic_clauseのwindowing_clauseを省略した場合、デフォルトでRANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROWになります。ウィンドウの最後の値はウィンドウの終端にあり、固定されていないため、このデフォルトは予期しない値を戻す場合があります。これは、現行の行が変化するに伴って変化します。正しい結果を得るには、windowing_clauseをRANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWINGとして指定します。または、windowing_clauseをRANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWINGとして指定することもできます。
関連項目:
このファンクションの戻り値が文字値である場合に、それに割り当てる照合を定義する照合導出ルールは、『Oracle Databaseグローバリゼーション・サポート・ガイド』の付録Cを参照してください。
例
次の例では、給与が最も低い従業員の雇用開始日を各行に戻します。
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の給与は同じであるため、Kochharの次の行にDe Haanがあります。Kochharが最初に表示されているのは、副問合せの行がhire_dateで順序付けられているためです。ただし、行が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次の2つの例では、一意キーで順序付けることによって、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次の2つの例では、論理オフセット(ROWSのかわりにRANGE)を使用すると、LAST_VALUEファンクションが決定的になることを示しています。ORDER BY式に重複値がある場合は、LAST_VALUEがexprの最大値になります。
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