TRANSFORM
TRANSFORM
람다 표현식(lambda expression)의 로직에 따라 배열을 변환해요.
본문
구문
TRANSFORM( array , lambda_expression )
인자
array
변환할 요소를 포함한 배열이에요. 배열은 반정형(semi-structured) 또는 정형(structured)일 수 있어요.
lambda_expression
각 배열 요소에 대한 변환 로직을 정의하는 람다 표현식이에요.
람다 표현식은 다음 구문에서 지정된 하나의 인자만 가져야 해요:
arg [ datatype ] - expr
반환 값
이 함수의 반환 타입은 람다 표현식 결과의 반정형 또는 정형 배열이에요.
두 인자 중 하나라도 NULL이면 함수는 오류를 보고하지 않고 NULL을 반환해요.
사용 시 유의사항
- 람다 인자의 데이터 타입이 명시적으로 지정되면 람다 호출 전에 배열 요소가 지정된 타입으로 강제 변환돼요. 강제 변환에 대한 정보는 Data type conversion을 참고하세요.
- 람다 인자에 대해 데이터 타입이 지정되지 않으면 그 데이터 타입은 입력 배열에서 다음과 같이 파생돼요:
- 입력 배열이 반정형이면 람다 인자의 데이터 타입은 VARIANT예요.
- 입력 배열이 정형이면 람다 인자의 데이터 타입은 배열 요소의 데이터 타입이에요.
- 반정형 배열 입력에 대해 반정형 배열이 반환돼요. 정형 배열 입력에 대해 람다 표현식 결과 타입의 정형 배열이 반환돼요.
예시
다음 예시들은 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 |
| ] |
+-----------------------+
테이블 데이터의 배열 요소 변환
orders라는 테이블에 order_id, order_date, order_detail 컬럼이 있다고 가정해요. order_detail 컬럼은 라인 항목, 구매 수량, 소계의 배열이에요. 테이블은 두 행의 데이터를 포함해요. 다음 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 |
| | | } |
| | | ] |
+----------+------------+-------------------------------------------+
TEMRANSFORM 함수와 OBJECT_DELETE 함수를 람다 표현식의 로직에서 함께 사용해 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 |
| ] |
+-------------------+