カテゴリ:

ウィンドウ関数の構文と使用法 (ランキング)

FIRST_VALUE

値が順序付けられたグループ内の最初の値を返します。

こちらもご参照ください。

LAST_VALUENTH_VALUE

構文

FIRST_VALUE( <expr> ) [ { IGNORE | RESPECT } NULLS ]
  OVER ( [ PARTITION BY <expr1> ] ORDER BY <expr2>  [ { ASC | DESC } ] [ NULLS { FIRST | LAST } ] [ <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

expr に NULL の値が含まれている場合に、 NULL の値を無視するか尊重するかを指定します。

  • IGNORE NULLS は NULL でない最初の値を返します。

  • RESPECT NULLS は、式の最初の値であれば NULL を返します。

デフォルト: RESPECT NULLS

使用上の注意

  • この関数はランク関連の関数であるため、ウィンドウを指定する必要があります。ウィンドウ句は、次のサブ句で構成されています。

    • 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 は、関数が計算されるウィンドウ内の行のサブセットを指定します。window_frame が指定されていない場合、デフォルトはウィンドウ全体です。

    ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING

    これは、ウィンドウフレームに次のデフォルトを指定するANSI標準とは異なります。

    RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW

window_frame の構文の詳細については、 ウィンドウ関数の構文と使用法 をご参照ください。

この例は、FIRST_VALUE関数を使用して、各カテゴリで最も低いメニュー項目を検索するクエリを示しています。クエリには、2つのORDER BY句が含まれています。1つは各パーティションの行の順序を制御し、もう1つは完全なクエリの出力の順序をソートします。この例で使用されているテーブルを作成し、ロードするには、 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;
Copy
+---------------+--------------------+----------------+---------------+
| 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 |
+---------------+--------------------+----------------+---------------+

次の例では、 menu_items テーブルを使用して、 FIRST_VALUE 、 NTH_VALUELAST_VALUE の3つの関連する関数の比較も行っています。

  • クエリは次を含む3行幅のスライディングウィンドウフレームを作成します。

    • 現在の行の前の行。

    • 現在の行。

    • 現在の行に続く行。

  • 呼び出し 2NTH_VALUE(menu_price_usd, 2) は、ウィンドウフレームの2番目の行(この場合は現在の行でもある)を指定します。

  • 現在の行がウィンドウフレームの最初の行である場合、参照する前の行がないため、 FIRST_VALUE はその行に対して NULL を返します。

  • フレームの境界がパーティションの行を超えることがありますが、存在しない行はウィンドウ関数の計算に含まれません。例えば、現在の行がパーティションの一番最初の行で、ウィンドウフレームが ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING の場合、リファレンスとなる前の行がないため、 FIRST_VALUE 関数はパーティションの最初の行の値を返します。

  • テーブルのデータからすると、3つの関数すべてで結果が一致することはありません。これらの関数は、フレーム内の各行について、 最初の値最後の値、または n番目の値 を選択し、値の選択は各パーティションに個別に適用されます。

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

この例は、IGNORE NULLSおよびRESPECT NULLSの違いを示しています。サンプルデータには、コスト値がNULLである行が含まれています。デフォルトのRESPECT NULLSの動作では、順序付けられたパーティションの最初の行にNULL値がある場合、FIRST_VALUEはNULLを返します。IGNORE NULLSでは、FIRST_VALUEはNULL値をスキップし、最初の非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;
Copy
+-----------+-----------+------------+--------------------+-------------------+
| 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 |
+-----------+-----------+------------+--------------------+-------------------+