카테고리:

윈도우 함수 구문 및 사용법 (순위 지정)

FIRST_VALUE

정렬된 값 그룹 내의 첫 번째 값을 반환합니다.

참고 항목:

LAST_VALUE , NTH_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 함수를 사용하여 각 카테고리에서 가장 저렴한 메뉴 항목을 찾는 쿼리를 보여줍니다. 쿼리에는 각 파티션의 행 순서를 제어하는 절 및 전체 쿼리의 출력을 정렬하는 절의 두 ORDER BY 절이 포함되어 있습니다. 이 예제에서 사용되는 테이블을 생성하고 로드하려면 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_VALUE, :doc:`/sql-reference/functions/last_value`의 3가지 관련 함수를 비교합니다.

  • 쿼리는 세 행 너비의 슬라이딩 윈도우 프레임을 생성하며, 여기에는 다음이 포함됩니다.

    • 현재 행에 선행하는 행.

    • 현재 행.

    • 현재 행 다음에 오는 행.

  • 2 호출의 NTH_VALUE(menu_price_usd, 2) 는 윈도우 프레임의 두 번째 행(이 경우, 현재 행이기도 함)을 지정합니다.

  • 현재 행이 윈도우 프레임의 맨 처음 행인 경우, 참조할 선행 행이 없으므로 FIRST_VALUE 는 해당 행에 대해 NULL을 반환합니다.

  • 프레임 경계가 파티션의 행을 넘어 확장되는 경우가 있지만 존재하지 않는 행은 윈도우 함수 계산에 포함되지 않습니다. 예를 들어 현재 행이 파티션의 첫 번째 행이고 윈도우 프레임이 ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING 인 경우 참조할 선행 행이 없으므로 FIRST_VALUE 함수는 파티션에서 첫 번째 행의 값을 반환합니다.

  • 테이블의 데이터가 주어졌을 때 세 가지 함수 모두에 대해 결과가 일치하지 않습니다. 이 함수는 프레임의 각 행에 대해 첫 번째, 마지막 또는 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 |
+-----------+-----------+------------+--------------------+-------------------+