Categorias:

Funções de janela (Relacionada à classificação, Quadro de janela)

FIRST_VALUE

Retorna o primeiro valor dentro de um grupo ordenado de valores.

Consulte também:

LAST_VALUE , NTH_VALUE

Sintaxe

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

Para obter mais detalhes sobre a sintaxe window_frame, consulte Sintaxe e utilização do quadro de janela.

Argumentos

expr

A expressão que determina o valor de retorno.

expr1

A expressão pela qual as linhas são particionadas. Você pode especificar uma única expressão ou uma lista de expressões separadas por vírgula. Por exemplo:

PARTITION BY column_1, column_2
expr2

A expressão pela qual se ordenam as linhas. Você pode especificar uma única expressão ou uma lista de expressões separadas por vírgula. Por exemplo:

ORDER BY column_3, column_4

Notas de uso

  • Para a compatibilidade com implementações desta função em outros sistemas, { IGNORE | RESPECT } NULLS também pode ser especificado nos argumentos para a função:

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

  • Se { IGNORE | RESPECT } NULLS não for especificado, o padrão será RESPECT NULLS (ou seja, um valor NULL será retornado se a expressão contiver um valor NULL e for o primeiro valor na expressão).

  • Esta função é uma função relacionada à classificação, portanto, deve especificar uma janela. Uma cláusula de janela consiste nas seguintes subcláusulas:

    • Subcláusula PARTITION BY <expr1> (opcional).

    • Subcláusula ORDER BY <expr2> (obrigatória). Para obter mais detalhes sobre opções adicionais de classificação suportadas (ordem de classificação, ordenação de valores NULL etc.), consulte a documentação para a construção da consulta ORDER BY, que segue as mesmas regras.

    • Subcláusula window_frame (opcional).

  • A ordem das linhas em uma janela (e portanto o resultado da consulta) é totalmente determinística somente se as chaves na cláusula ORDER BY tornarem cada linha única. Considere o seguinte exemplo:

    ... OVER (PARTITION BY p ORDER BY o COLLATE 'lower') ...
    

    O resultado da consulta pode variar se qualquer partição contiver valores da coluna o que sejam idênticos, ou seriam idênticos em uma comparação que não diferencia maiúsculas e minúsculas.

  • A cláusula ORDER BY dentro da cláusula OVER controla a ordem das linhas somente dentro da janela, não a ordem das linhas na saída de toda a consulta. Para controlar a ordem de saída, use uma cláusula ORDER BY separada no nível mais externo da consulta.

  • O window_frame opcional (cumulativo ou deslizante) especifica o subconjunto de linhas dentro do intervalo para o qual a função é calculada. Se nenhum window_frame for especificado, o padrão é a janela inteira:

    ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING

    Observe que isso se desvia da norma ANSI, que especifica o seguinte padrão para quadros de janelas:

    RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW

    Para obter mais detalhes sobre quadros de janela, incluindo sintaxe e exemplos, consulte Sintaxe e utilização do quadro de janela.

Exemplos

Isto mostra uma consulta simples usando FIRST_VALUE(). Esta consulta contém duas subcláusulas ORDER BY, uma para controlar a ordem das linhas em cada partição, e outra para controlar a ordem da saída da consulta completa.

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 |
+---------+---------+---------------+

A próxima consulta compara as saídas de FIRST_VALUE, NTH_VALUE e LAST_VALUE. Note que:

  • A consulta cria um quadro de janela deslizante que tem 3 linhas de largura, que contém:

    • A linha que precede a linha atual.

    • A linha atual.

    • A linha que segue a linha atual.

  • A 2 na chamada NTH_VALUE(i, 2) especifica a segunda linha no quadro da janela (que, neste caso, é também a linha atual).

  • Quando a linha atual é a primeira linha no quadro da janela, não há linha anterior para referência, portanto FIRST_VALUE() retorna um NULL para aquela linha.

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 |
+---------------+-----------+---+-----------+---------+----------+