- 类别:
:doc:`/sql-reference/functions-analytic`(排名相关、窗口框架)
LAST_VALUE¶
返回一组有序值中的最后一个值。
- 另请参阅:
语法¶
LAST_VALUE( <expr> ) [ { IGNORE | RESPECT } NULLS ]
OVER ( [ PARTITION BY <expr1> ] ORDER BY <expr2> [ { ASC | DESC } ] [ <window_frame> ] )
有关 window_frame
语法的详细信息,请参阅 窗口框架语法和用法。
实参¶
expr
确定返回值的表达式。
expr1
用于对行进行分区的表达式。您可以指定单个表达式或以逗号分隔的表达式列表。例如:
PARTITION BY column_1, column_2
expr2
用于对行进行排序的表达式。您可以指定单个表达式或以逗号分隔的表达式列表。例如:
ORDER BY column_3, column_4
使用说明¶
为了与其他系统中该函数的实现兼容,也可以在该函数的实参中指定
{ IGNORE | RESPECT } NULLS
:LAST_VALUE( <expr> [ { IGNORE | RESPECT } NULLS ] ) OVER ...
如果未指定
{ IGNORE | RESPECT } NULLS
,则默认值为RESPECT NULLS
。例如,如果表达式包含 NULL 值,并且它是表达式中的最后一个值,则返回 NULL 值。
此函数是与排名相关的函数,因此它必须指定一个窗口。窗口子句由以下分子句组成:
PARTITION BY <expr1>
分子句(可选)。ORDER BY <expr2>
分子句(必需)。有关其他受支持的排序选项(排序顺序、NULL 值排序等)的详细信息,请参阅 ORDER BY 查询构造的文档,该构造遵循相同的规则。window_frame
分子句(可选)。
仅当 ORDER BY 子句中的键使每一行都唯一时,窗口中行的顺序(以及查询结果)才是完全确定的。请参考以下示例:
... OVER (PARTITION BY p ORDER BY o COLLATE 'lower') ...
如果任何分区包含相同的列
o
值,或者在不区分大小写的比较中相同,则查询结果可能会有所不同。OVER 子句中的 ORDER BY 子句只控制窗口中行的顺序,而不控制整个查询输出中行的顺序。若要控制输出顺序,请在查询的最外层使用单独的 ORDER BY 子句。
可选的
window_frame
(累积或滑动)指定计算函数的窗口中行的子集。对于窗口框架,此函数仅支持基于 ROWS 的窗口框架,不支持基于 RANGE 的窗口框架。
- 支持:
ROWS BETWEEN ... AND ...
- 不支持:
RANGE BETWEEN ... AND ...
如果未指定
window_frame
,默认为整个窗口:ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
这与 ANSI 标准 不同,后者为窗口框架指定了以下默认值:
RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
有关窗口框架的更多详细信息(包括语法和示例),请参阅 窗口框架语法和用法。
示例¶
SELECT
column1,
column2,
LAST_VALUE(column2) OVER (PARTITION BY column1 ORDER BY column2) AS column2_last
FROM VALUES
(1, 10), (1, 11), (1, 12),
(2, 20), (2, 21), (2, 22);
+---------+---------+--------------+
| COLUMN1 | COLUMN2 | COLUMN2_LAST |
|---------+---------+--------------|
| 1 | 10 | 12 |
| 1 | 11 | 12 |
| 1 | 12 | 12 |
| 2 | 20 | 22 |
| 2 | 21 | 22 |
| 2 | 22 | 22 |
+---------+---------+--------------+
下一个查询对比 FIRST_VALUE
、NTH_VALUE
和 LAST_VALUE
的输出。请注意:
该查询创建一个 3 行宽的滑动窗口框架,其中包含:
当前行前面的行。
当前行。
当前行后面的行。
调用
NTH_VALUE(i, 2)
中的2
指定了窗口框架中的第二行(在本例中也是当前行)。当前行是窗口框架中的第一行时,没有前面的行可以引用,因此
FIRST_VALUE()
为该行返回 NULL。
SELECT
partition_col, order_col, i,
FIRST_VALUE(i) OVER (PARTITION BY partition_col ORDER BY order_col
ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS FIRST_VAL,
NTH_VALUE(i, 2) OVER (PARTITION BY partition_col ORDER BY order_col
ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS NTH_VAL,
LAST_VALUE(i) OVER (PARTITION BY partition_col ORDER BY order_col
ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS LAST_VAL
FROM demo1
ORDER BY partition_col, i, order_col;
+---------------+-----------+---+-----------+---------+----------+
| PARTITION_COL | ORDER_COL | I | FIRST_VAL | NTH_VAL | LAST_VAL |
|---------------+-----------+---+-----------+---------+----------|
| 1 | 1 | 1 | NULL | 1 | 2 |
| 1 | 2 | 2 | 1 | 2 | 3 |
| 1 | 3 | 3 | 2 | 3 | 4 |
| 1 | 4 | 4 | 3 | 4 | 5 |
| 1 | 5 | 5 | 4 | 5 | 5 |
| 2 | 1 | 1 | NULL | 1 | 2 |
| 2 | 2 | 2 | 1 | 2 | 3 |
| 2 | 3 | 3 | 2 | 3 | 4 |
| 2 | 4 | 4 | 3 | 4 | 4 |
+---------------+-----------+---+-----------+---------+----------+