类别:

:doc:`/sql-reference/functions-analytic`(排名相关、窗口框架)

FIRST_VALUE

返回一组有序值中的第一个值。

另请参阅:

LAST_VALUENTH_VALUE

语法

FIRST_VALUE( <expr> ) [ { IGNORE | RESPECT } NULLS ]
                      OVER ( [ PARTITION BY <expr1> ] ORDER BY <expr2>  [ { ASC | DESC } ] [ <window_frame> ] )
Copy

有关 window_frame 语法的详细信息,请参阅 窗口框架语法和用法

实参

expr

确定返回值的表达式。

expr1

用于对行进行分区的表达式。您可以指定单个表达式或以逗号分隔的表达式列表。例如:

PARTITION BY column_1, column_2
Copy
expr2

用于对行进行排序的表达式。您可以指定单个表达式或以逗号分隔的表达式列表。例如:

ORDER BY column_3, column_4
Copy

使用说明

  • 为了与其他系统中该函数的实现兼容,也可以在该函数的实参中指定 { IGNORE | RESPECT } NULLS

    FIRST_VALUE( <expr> [ { IGNORE | RESPECT } NULLS ] ) OVER ...

  • 如果未指定 { IGNORE | RESPECT } NULLS,则默认值为 :code:`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') ...
    
    Copy

    如果任何分区包含相同的列 o 值,或者在不区分大小写的比较中相同,则查询结果可能会有所不同。

  • OVER 子句中的 ORDER BY 子句只控制窗口中行的顺序,而不控制整个查询输出中行的顺序。若要控制输出顺序,请在查询的最外层使用单独的 ORDER BY 子句。

  • 可选的 window_frame`(累积或滑动)指定计算函数的窗口中行的子集。如果未指定 :samp:`window_frame,默认为整个窗口:

    ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING

    请注意,这偏离了 ANSI 标准,该标准为窗口框架指定了以下默认值:

    RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW

    有关窗口框架的更多详细信息(包括语法和示例),请参阅 窗口框架语法和用法

示例

这显示了一个使用 FIRST_VALUE() 的简单查询。该查询包含两个 ORDER BY 分子句,一个用于控制每个分区中行的顺序,另一个用于控制整个查询的输出顺序。

SELECT
        column1,
        column2,
        FIRST_VALUE(column2) OVER (PARTITION BY column1 ORDER BY column2 NULLS LAST) AS column2_first
    FROM VALUES
       (1, 10), (1, 11), (1, null), (1, 12),
       (2, 20), (2, 21), (2, 22)
    ORDER BY column1, column2;
+---------+---------+---------------+
| COLUMN1 | COLUMN2 | COLUMN2_FIRST |
|---------+---------+---------------|
|       1 |      10 |            10 |
|       1 |      11 |            10 |
|       1 |      12 |            10 |
|       1 |    NULL |            10 |
|       2 |      20 |            20 |
|       2 |      21 |            20 |
|       2 |      22 |            20 |
+---------+---------+---------------+
Copy

下一个查询对比 FIRST_VALUENTH_VALUELAST_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 |
+---------------+-----------+---+-----------+---------+----------+
Copy
语言: 中文