- カテゴリ:
半構造化データ関数と構造化データ関数 (高次)
TRANSFORM¶
ラムダ式のロジックに基づいて、 配列 を変換します。
- こちらもご参照ください。
構文¶
TRANSFORM( <array> , <lambda_expression> )
引数¶
array変換する要素を含む配列。配列は半構造化でも構造化でもかまいません。
lambda_expression各配列要素の変換ロジックを定義する ラムダ式。
ラムダ式には、以下の構文で指定された引数1つのみを使用する必要があります。
<arg> [ <datatype> ] -> <expr>
戻り値¶
この関数の戻り値の型は、ラムダ式の結果の半構造化配列または構造化配列です。
引数が NULL の場合、関数はエラーを報告せずに NULL を返します。
使用上の注意¶
例¶
以下の例では、 TRANSFORM 関数を使用しています。
配列の各要素を値で乗算します。¶
TRANSFORM 関数を使用して、配列の各要素を2で乗算します。
SELECT TRANSFORM([1, 2, 3], a INT -> a * 2) AS "Multiply by Two";
+-----------------+
| Multiply by Two |
|-----------------|
| [ |
| 2, |
| 4, |
| 6 |
| ] |
+-----------------+
この例は前の例と同じですが、この例では INT 型の構造化配列を指定しています。
SELECT TRANSFORM([1, 2, 3]::ARRAY(INT), a INT -> a * 2) AS "Multiply by Two (Structured)";
+------------------------------+
| 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";
+-----------------------+
| Return Values |
|-----------------------|
| [ |
| "50 is the number", |
| "75 is the number", |
| "25 is the number" |
| ] |
+-----------------------+
テーブルデータの配列要素を変換する¶
order_id、 order_date、 order_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;
+----------+------------+-------------------------------------------+
| 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;
+----------+------------+-------------------------------------------+
| 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;
+----------+------------+-------------------------------------------+
| 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;
+------+------+
| 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;
+-------------------+
| TRANSFORM_COL_REF |
|-------------------|
| [ |
| 11, |
| 12, |
| 13 |
| ] |
| [ |
| 3, |
| 4, |
| 5 |
| ] |
| [ |
| undefined, |
| undefined, |
| undefined |
| ] |
+-------------------+