- Categorias:
Sintaxe e uso da função de janela (classificação)
FIRST_VALUE¶
Retorna o primeiro valor dentro de um grupo ordenado de valores.
- Consulte também:
Sintaxe¶
FIRST_VALUE( <expr> ) [ { IGNORE | RESPECT } NULLS ]
OVER ( [ PARTITION BY <expr1> ] ORDER BY <expr2> [ { ASC | DESC } ] [ NULLS { FIRST | LAST } ] [ <window_frame> ] )
Para uma sintaxe window_frame detalhada, consulte Sintaxe e uso da função de janela.
Argumentos¶
exprA expressão que determina o valor de retorno.
expr1A 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
expr2A 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
{ IGNORE | RESPECT } NULLSSe você deve ignorar ou respeitar os valores de NULL quando um
exprcontiver valores de NULL:IGNORE NULLSretorna o primeiro valor diferente de NULL.RESPECT NULLSretorna um valor NULL se for o primeiro valor na expressão.
Padrão:
RESPECT NULLS
Notas de uso¶
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 detalhes sobre outras opções de ordenação compatíveis (ordem de classificação, ordenação dos valores NULL e assim por diante), consulte a documentação da cláusula 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
oque 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_frameopcional especifica o subconjunto de linhas dentro da janela para as quais a função é calculada. Se nenhumwindow_framefor especificado, o padrão é a janela inteira:ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWINGObserve 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 uma sintaxe window_frame detalhada, consulte Sintaxe e uso da função de janela.
Exemplos¶
This example shows a query that uses the FIRST_VALUE function to find the cheapest menu item in each category. The query contains two ORDER BY clauses: one to control the order of rows in each partition, and one to sort the output of the full query. To create and load the table that is used in this example, see Criação e carregamento da tabela menu_items.
SELECT menu_category, menu_item_name, menu_price_usd,
FIRST_VALUE(menu_item_name) OVER (PARTITION BY menu_category ORDER BY menu_price_usd) AS cheapest_item
FROM menu_items
WHERE menu_category IN ('Beverage', 'Dessert', 'Snack')
ORDER BY menu_category, menu_price_usd
LIMIT 12;
+---------------+--------------------+----------------+---------------+
| MENU_CATEGORY | MENU_ITEM_NAME | MENU_PRICE_USD | CHEAPEST_ITEM |
|---------------+--------------------+----------------+---------------|
| Beverage | Bottled Water | 2.00 | Bottled Water |
| Beverage | Iced Tea | 3.00 | Bottled Water |
| Beverage | Bottled Soda | 3.00 | Bottled Water |
| Beverage | Lemonade | 3.50 | Bottled Water |
| Dessert | Popsicle | 3.00 | Popsicle |
| Dessert | Ice Cream Sandwich | 4.00 | Popsicle |
| Dessert | Mango Sticky Rice | 5.00 | Popsicle |
| Dessert | Sugar Cone | 6.00 | Popsicle |
| Dessert | Waffle Cone | 6.00 | Popsicle |
| Dessert | Two Scoop Bowl | 7.00 | Popsicle |
| Snack | Spring Mix Salad | 6.00 | Fried Pickles |
| Snack | Fried Pickles | 6.00 | Fried Pickles |
+---------------+--------------------+----------------+---------------+
The following example also uses the menu_items table to compare three related functions: FIRST_VALUE,
NTH_VALUE, and LAST_VALUE:
A consulta cria um quadro de janela deslizante com três linhas de largura, que contém:
A linha que precede a linha atual.
A linha atual.
A linha que segue a linha atual.
The
2in the callNTH_VALUE(menu_price_usd, 2)specifies the second row in the window frame (which, in this case, is also the current row).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.
Às vezes, os limites da estrutura se estendem além das linhas em uma partição, mas as linhas inexistentes não são incluídas nos cálculos da função de janela. Por exemplo, quando a linha atual é a primeira linha da partição e o quadro de janela é
ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING, não há nenhuma linha anterior a ser referenciada, portanto, a função FIRST_VALUE retorna o valor da primeira linha da partição.Os resultados nunca são iguais para todas as três funções, considerando os dados da tabela. Essas funções selecionam os valores first, last ou nth para cada linha do quadro, e a seleção de valores se aplica separadamente a cada partição.
SELECT menu_category, menu_item_name, menu_price_usd,
FIRST_VALUE(menu_price_usd) OVER (PARTITION BY menu_category ORDER BY menu_price_usd
ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS first_val,
NTH_VALUE(menu_price_usd, 2) OVER (PARTITION BY menu_category ORDER BY menu_price_usd
ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS nth_val,
LAST_VALUE(menu_price_usd) OVER (PARTITION BY menu_category ORDER BY menu_price_usd
ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS last_val
FROM menu_items
WHERE menu_category = 'Dessert'
ORDER BY menu_price_usd;
+---------------+--------------------+----------------+-----------+---------+----------+
| MENU_CATEGORY | MENU_ITEM_NAME | MENU_PRICE_USD | FIRST_VAL | NTH_VAL | LAST_VAL |
|---------------+--------------------+----------------+-----------+---------+----------|
| Dessert | Popsicle | 3.00 | 3.00 | 4.00 | 4.00 |
| Dessert | Ice Cream Sandwich | 4.00 | 3.00 | 4.00 | 5.00 |
| Dessert | Mango Sticky Rice | 5.00 | 4.00 | 5.00 | 6.00 |
| Dessert | Sugar Cone | 6.00 | 6.00 | 6.00 | 7.00 |
| Dessert | Waffle Cone | 6.00 | 5.00 | 6.00 | 6.00 |
| Dessert | Two Scoop Bowl | 7.00 | 6.00 | 7.00 | 7.00 |
+---------------+--------------------+----------------+-----------+---------+----------+
Este exemplo demonstra a diferença entre IGNORE NULLS e RESPECT NULLS. Os dados de amostra incluem linhas em que o valor de custo é NULL. Com o comportamento RESPECT NULLS padrão, se a primeira linha na partição ordenada tiver um valor NULL, FIRST_VALUE retornará NULL. Com IGNORE NULLS, FIRST_VALUE ignora valores NULL e retorna o primeiro valor diferente de NULL.
SELECT item_name, item_cost, item_price,
FIRST_VALUE(item_cost) RESPECT NULLS
OVER (ORDER BY item_price) AS first_cost_respect,
FIRST_VALUE(item_cost) IGNORE NULLS
OVER (ORDER BY item_price) AS first_cost_ignore
FROM VALUES
('Pretzel', NULL, 3.00),
('Corn Dog', NULL, 4.00),
('Hot Dog', 1.50, 5.00),
('Sandwich', 2.50, 6.00)
AS menu(item_name, item_cost, item_price)
ORDER BY item_price;
+-----------+-----------+------------+--------------------+-------------------+
| ITEM_NAME | ITEM_COST | ITEM_PRICE | FIRST_COST_RESPECT | FIRST_COST_IGNORE |
|-----------+-----------+------------+--------------------+-------------------|
| Pretzel | NULL | 3.00 | NULL | 1.50 |
| Corn Dog | NULL | 4.00 | NULL | 1.50 |
| Hot Dog | 1.50 | 5.00 | NULL | 1.50 |
| Sandwich | 2.50 | 6.00 | NULL | 1.50 |
+-----------+-----------+------------+--------------------+-------------------+