カテゴリ:

半構造化データ関数と構造化データ関数 (高次)

TRANSFORM

ラムダ式のロジックに基づいて、 配列 を変換します。

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

Snowflakeの高階関数でラムダ関数をデータ上で使用する

構文

TRANSFORM( <array> , <lambda_expression> )
Copy

引数

array

変換する要素を含む配列。配列は半構造化でも構造化でもかまいません。

lambda_expression

各配列要素の変換ロジックを定義する ラムダ式

ラムダ式には、以下の構文で指定された引数1つのみを使用する必要があります。

<arg> [ <datatype> ] -> <expr>
Copy

戻り値

この関数の戻り値の型は、ラムダ式の結果の半構造化配列または構造化配列です。

引数が NULL の場合、関数はエラーを報告せずに NULL を返します。

使用上の注意

  • ラムダ引数のデータ型が明示的に指定されている場合、配列要素はラムダ呼び出しの前に指定された型に強制されます。強制については、 データ型の変換 をご参照ください。

  • ラムダ引数にデータ型が指定されていない場合、そのデータ型は入力配列から以下のように導出されます。

    • 入力配列が半構造化データの場合、ラムダ引数のデータ型は VARIANT になります。

    • 入力配列が構造化されている場合、ラムダ引数のデータ型は配列要素のデータ型になります。

  • 半構造化配列の入力の場合は、半構造化配列を返します。構造化配列入力の場合は、ラムダ式の結果型の構造化配列を返します。

以下の例では、 TRANSFORM 関数を使用しています。

配列の各要素を値で乗算します。

TRANSFORM 関数を使用して、配列の各要素を2で乗算します。

SELECT TRANSFORM([1, 2, 3], a INT -> a * 2) AS "Multiply by Two";
Copy
+-----------------+
| Multiply by Two |
|-----------------|
| [               |
|   2,            |
|   4,            |
|   6             |
| ]               |
+-----------------+

この例は前の例と同じですが、この例では INT 型の構造化配列を指定しています。

SELECT TRANSFORM([1, 2, 3]::ARRAY(INT), a INT -> a * 2) AS "Multiply by Two (Structured)";
Copy
+------------------------------+
| Multiply by Two (Structured) |
|------------------------------|
| [                            |
|   2,                         |
|   4,                         |
|   6                          |
| ]                            |
+------------------------------+

テキストを追加した値を配列で返します。

TRANSFORM 関数を使用して、配列内の各オブジェクトの値を返し、各オブジェクトにテキストを追加します。

SELECT TRANSFORM(
    [
      {'name':'Pat', 'value': 50},
      {'name':'Terry', 'value': 75},
      {'name':'Dana', 'value': 25}
    ],
    c -> c:value || ' is the number'
  ) AS "Return Values";
Copy
+-----------------------+
| Return Values         |
|-----------------------|
| [                     |
|   "50 is the number", |
|   "75 is the number", |
|   "25 is the number"  |
| ]                     |
+-----------------------+

テーブルデータの配列要素を変換する

order_idorder_dateorder_detail の列を持つ orders という名前のテーブルがあるとします。order_detail 列は、行項目、購入数量、小計の配列です。テーブルには2行のデータがあります。次の SQL ステートメントは、このテーブルを作成し、行を挿入します。

CREATE OR REPLACE TABLE orders AS
  SELECT 1 AS order_id, '2024-01-01' AS order_date, [
    {'item':'UHD Monitor', 'quantity':3, 'subtotal':1500},
    {'item':'Business Printer', 'quantity':1, 'subtotal':1200}
  ] AS order_detail
  UNION
  SELECT 2 AS order_id, '2024-01-02' AS order_date, [
    {'item':'Laptop', 'quantity':5, 'subtotal':7500},
    {'item':'Noise-canceling Headphones', 'quantity':5, 'subtotal':1000}
  ] AS order_detail;

SELECT * FROM orders;
Copy
+----------+------------+-------------------------------------------+
| ORDER_ID | ORDER_DATE | ORDER_DETAIL                              |
|----------+------------+-------------------------------------------|
|        1 | 2024-01-01 | [                                         |
|          |            |   {                                       |
|          |            |     "item": "UHD Monitor",                |
|          |            |     "quantity": 3,                        |
|          |            |     "subtotal": 1500                      |
|          |            |   },                                      |
|          |            |   {                                       |
|          |            |     "item": "Business Printer",           |
|          |            |     "quantity": 1,                        |
|          |            |     "subtotal": 1200                      |
|          |            |   }                                       |
|          |            | ]                                         |
|        2 | 2024-01-02 | [                                         |
|          |            |   {                                       |
|          |            |     "item": "Laptop",                     |
|          |            |     "quantity": 5,                        |
|          |            |     "subtotal": 7500                      |
|          |            |   },                                      |
|          |            |   {                                       |
|          |            |     "item": "Noise-canceling Headphones", |
|          |            |     "quantity": 5,                        |
|          |            |     "subtotal": 1000                      |
|          |            |   }                                       |
|          |            | ]                                         |
+----------+------------+-------------------------------------------+

TRANSFORM 関数を使用して、 orders テーブルの各配列に unit_price 要素を追加します。

SELECT order_id,
       order_date,
       TRANSFORM(o.order_detail, i -> OBJECT_INSERT(
         i,
         'unit_price',
         (i:subtotal / i:quantity)::NUMERIC(10,2)
         )
       ) AS order_detail_with_unit_price
  FROM orders o;
Copy
+----------+------------+-------------------------------------------+
| ORDER_ID | ORDER_DATE | ORDER_DETAIL_WITH_UNIT_PRICE              |
|----------+------------+-------------------------------------------|
|        1 | 2024-01-01 | [                                         |
|          |            |   {                                       |
|          |            |     "item": "UHD Monitor",                |
|          |            |     "quantity": 3,                        |
|          |            |     "subtotal": 1500,                     |
|          |            |     "unit_price": 500                     |
|          |            |   },                                      |
|          |            |   {                                       |
|          |            |     "item": "Business Printer",           |
|          |            |     "quantity": 1,                        |
|          |            |     "subtotal": 1200,                     |
|          |            |     "unit_price": 1200                    |
|          |            |   }                                       |
|          |            | ]                                         |
|        2 | 2024-01-02 | [                                         |
|          |            |   {                                       |
|          |            |     "item": "Laptop",                     |
|          |            |     "quantity": 5,                        |
|          |            |     "subtotal": 7500,                     |
|          |            |     "unit_price": 1500                    |
|          |            |   },                                      |
|          |            |   {                                       |
|          |            |     "item": "Noise-canceling Headphones", |
|          |            |     "quantity": 5,                        |
|          |            |     "subtotal": 1000,                     |
|          |            |     "unit_price": 200                     |
|          |            |   }                                       |
|          |            | ]                                         |
+----------+------------+-------------------------------------------+

ラムダ式のロジックで OBJECT_DELETE 関数とともに TRANSFORM 関数を使用し、 orders テーブルから各配列の quantity 要素を削除します。

SELECT order_id,
       order_date,
       TRANSFORM(o.order_detail, i -> OBJECT_DELETE(
         i,
         'quantity'
         )
       ) AS order_detail_without_quantity
  FROM orders o;
Copy
+----------+------------+-------------------------------------------+
| ORDER_ID | ORDER_DATE | ORDER_DETAIL_WITHOUT_QUANTITY             |
|----------+------------+-------------------------------------------|
|        1 | 2024-01-01 | [                                         |
|          |            |   {                                       |
|          |            |     "item": "UHD Monitor",                |
|          |            |     "subtotal": 1500                      |
|          |            |   },                                      |
|          |            |   {                                       |
|          |            |     "item": "Business Printer",           |
|          |            |     "subtotal": 1200                      |
|          |            |   }                                       |
|          |            | ]                                         |
|        2 | 2024-01-02 | [                                         |
|          |            |   {                                       |
|          |            |     "item": "Laptop",                     |
|          |            |     "subtotal": 7500                      |
|          |            |   },                                      |
|          |            |   {                                       |
|          |            |     "item": "Noise-canceling Headphones", |
|          |            |     "subtotal": 1000                      |
|          |            |   }                                       |
|          |            | ]                                         |
+----------+------------+-------------------------------------------+

ラムダ式でテーブル列を参照し、テーブルデータの配列要素を変換する

ARRAY 型の列と INT 型の列を持つテーブルを作成します。

CREATE OR REPLACE TABLE transform_column_ref_demo AS
  SELECT [ 1, 2, 3 ] AS col1, 10 AS col2
  UNION
  SELECT [ 4, 5, 6 ] AS col1, -1 AS col2
  UNION
  SELECT [ 7, 8, 9 ] AS col1, NULL AS col2;

SELECT * FROM transform_column_ref_demo;
Copy
+------+------+
| COL1 | COL2 |
|------+------|
| [    |   10 |
|   1, |      |
|   2, |      |
|   3  |      |
| ]    |      |
| [    |   -1 |
|   4, |      |
|   5, |      |
|   6  |      |
| ]    |      |
| [    | NULL |
|   7, |      |
|   8, |      |
|   9  |      |
| ]    |      |
+------+------+

TRANSFORM 関数を使用して、 col2 の値を各行の各配列要素の値に追加します。

SELECT TRANSFORM(col1, v INT -> v + col2) AS transform_col_ref
  FROM transform_column_ref_demo;
Copy
+-------------------+
| TRANSFORM_COL_REF |
|-------------------|
| [                 |
|   11,             |
|   12,             |
|   13              |
| ]                 |
| [                 |
|   3,              |
|   4,              |
|   5               |
| ]                 |
| [                 |
|   undefined,      |
|   undefined,      |
|   undefined       |
| ]                 |
+-------------------+