FLATTEN (Lakehouse v1)
중첩된 JSON 데이터를 각 요소나 필드가 별도의 행으로 표현되는 테이블 형식으로 변환합니다.
SQL Syntax
섹션 제목: “SQL Syntax”[LATERAL] FLATTEN ( INPUT => <expr> [ , PATH => <expr> ] [ , OUTER => TRUE | FALSE ] [ , RECURSIVE => TRUE | FALSE ] [ , MODE => 'OBJECT' | 'ARRAY' | 'BOTH' ] )| 매개변수 / 키워드 | 설명 | 기본값 |
|---|---|---|
| INPUT | 평탄화할 JSON 또는 배열 데이터를 지정합니다. | - |
| PATH | 평탄화할 입력 데이터 내 배열 또는 객체의 경로를 지정합니다. | - |
| OUTER | TRUE로 설정하면 결과가 0건인 행도 출력에 포함되지만, 해당 행의 KEY, INDEX, VALUE 열 값은 NULL로 설정됩니다. | FALSE |
| RECURSIVE | TRUE로 설정하면 중첩된 요소를 계속해서 평탄화합니다. | FALSE |
| MODE | 객체만(‘OBJECT’), 배열만(‘ARRAY’), 또는 둘 다(‘BOTH’) 평탄화할지 제어합니다. | ‘BOTH’ |
| LATERAL | LATERAL은 FROM 절에서 LATERAL 키워드 왼쪽에 정의된 열을 참조하는 데 사용하는 선택적 키워드입니다. LATERAL을 사용하면 앞에 나온 테이블 식과 함수가 서로를 참조할 수 있습니다. | - |
다음 표는 FLATTEN 함수의 출력 열을 설명합니다.
| 열 | 설명 |
|---|---|
| SEQ | 입력에 연결된 고유한 시퀀스 번호입니다. |
| KEY | 확장된 값의 키입니다. 평탄화된 요소에 키가 없으면 NULL로 설정됩니다. |
| PATH | 평탄화된 요소의 경로입니다. |
| INDEX | 요소가 배열이면 이 열에 해당 인덱스가 담기고, 그렇지 않으면 NULL로 설정됩니다. |
| VALUE | 평탄화된 요소의 값입니다. |
| THIS | 이 열은 현재 평탄화 중인 요소를 나타냅니다. |
SQL Examples
섹션 제목: “SQL Examples”SQL Examples 1: PATH, OUTER, RECURSIVE, MODE 매개변수 살펴보기
섹션 제목: “SQL Examples 1: PATH, OUTER, RECURSIVE, MODE 매개변수 살펴보기”이 예제는 PATH, OUTER, RECURSIVE, MODE 매개변수에 따른 FLATTEN 함수의 동작을 보여줍니다.
SELECT *FROM FLATTEN ( INPUT => PARSE_JSON ( '{"name": "John", "languages": ["English", "Spanish", "French"], "address": {"city": "New York", "state": "NY"}}' ) );
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐│ seq │ key │ path │ index │ value │ this │├────────┼──────────────────┼──────────────────┼──────────────────┼──────────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────┤│ 1 │ address │ address │ NULL │ {"city":"New York","state":"NY"} │ {"address":{"city":"New York","state":"NY"},"languages":["English","Spanish","French"],"name":"John"} ││ 1 │ languages │ languages │ NULL │ ["English","Spanish","French"] │ {"address":{"city":"New York","state":"NY"},"languages":["English","Spanish","French"],"name":"John"} ││ 1 │ name │ name │ NULL │ "John" │ {"address":{"city":"New York","state":"NY"},"languages":["English","Spanish","French"],"name":"John"} │└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-- PATH helps in selecting elements at a specific path from the original JSON data.SELECT *FROM FLATTEN ( INPUT => PARSE_JSON ( '{"name": "John", "languages": ["English", "Spanish", "French"], "address": {"city": "New York", "state": "NY"}}' ), PATH => 'languages' );
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐│ seq │ key │ path │ index │ value │ this │├────────┼──────────────────┼──────────────────┼──────────────────┼───────────────────┼────────────────────────────────┤│ 1 │ NULL │ languages[0] │ 0 │ "English" │ ["English","Spanish","French"] ││ 1 │ NULL │ languages[1] │ 1 │ "Spanish" │ ["English","Spanish","French"] ││ 1 │ NULL │ languages[2] │ 2 │ "French" │ ["English","Spanish","French"] │└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-- RECURSIVE enables recursive flattening of nested structures.SELECT *FROM FLATTEN ( INPUT => PARSE_JSON ( '{"name": "John", "languages": ["English", "Spanish", "French"], "address": {"city": "New York", "state": "NY"}}' ), RECURSIVE => TRUE );
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐│ seq │ key │ path │ index │ value │ this │├────────┼──────────────────┼──────────────────┼──────────────────┼──────────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────┤│ 1 │ address │ address │ NULL │ {"city":"New York","state":"NY"} │ {"address":{"city":"New York","state":"NY"},"languages":["English","Spanish","French"],"name":"John"} ││ 1 │ city │ address.city │ NULL │ "New York" │ {"city":"New York","state":"NY"} ││ 1 │ state │ address.state │ NULL │ "NY" │ {"city":"New York","state":"NY"} ││ 1 │ languages │ languages │ NULL │ ["English","Spanish","French"] │ {"address":{"city":"New York","state":"NY"},"languages":["English","Spanish","French"],"name":"John"} ││ 1 │ NULL │ languages[0] │ 0 │ "English" │ ["English","Spanish","French"] ││ 1 │ NULL │ languages[1] │ 1 │ "Spanish" │ ["English","Spanish","French"] ││ 1 │ NULL │ languages[2] │ 2 │ "French" │ ["English","Spanish","French"] ││ 1 │ name │ name │ NULL │ "John" │ {"address":{"city":"New York","state":"NY"},"languages":["English","Spanish","French"],"name":"John"} │└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-- MODE specifies whether only objects ('OBJECT'), only arrays ('ARRAY'), or both ('BOTH') should be flattened.-- In this example, MODE => 'ARRAY' is used, which means that only arrays within the JSON data will be flattened.SELECT *FROM FLATTEN ( INPUT => PARSE_JSON ( '{"name": "John", "languages": ["English", "Spanish", "French"], "address": {"city": "New York", "state": "NY"}}' ), MODE => 'ARRAY' );
---
-- OUTER determines the inclusion of zero-row expansions in the output.-- In this first example, OUTER => TRUE is used with an empty JSON array, which results in zero-row expansions.-- Rows are included in the output even when there are no values to flatten.SELECT *FROM FLATTEN (INPUT => PARSE_JSON ('[]'), OUTER => TRUE);
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────┐│ seq │ key │ path │ index │ value │ this │├────────┼──────────────────┼──────────────────┼──────────────────┼───────────────────┼───────────────────┤│ 1 │ NULL │ NULL │ NULL │ NULL │ NULL │└─────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-- In this second example, OUTER is omitted, and the output shows how rows with zero results are not included when OUTER is not specified.SELECT *FROM FLATTEN (INPUT => PARSE_JSON ('[]'));SQL Examples 2: LATERAL FLATTEN 살펴보기
섹션 제목: “SQL Examples 2: LATERAL FLATTEN 살펴보기”이 예제는 LATERAL 키워드와 함께 사용할 때의 FLATTEN 함수 동작을 보여줍니다.
-- Create a table for Tim Hortons transactions with multiple itemsCREATE TABLE tim_hortons_transactions ( transaction_id INT, customer_id INT, items VARIANT);
-- Insert data for Tim Hortons transactions with multiple itemsINSERT INTO tim_hortons_transactions (transaction_id, customer_id, items)VALUES (101, 1, parse_json('[{"item":"coffee", "price":2.50}, {"item":"donut", "price":1.20}]')), (102, 2, parse_json('[{"item":"bagel", "price":1.80}, {"item":"muffin", "price":2.00}]')), (103, 3, parse_json('[{"item":"timbit_assortment", "price":5.00}]'));
-- Show Tim Hortons transactions with multiple items using LATERAL FLATTENSELECT t.transaction_id, t.customer_id, f.value:item::STRING AS purchased_item, f.value:price::FLOAT AS priceFROM tim_hortons_transactions t, LATERAL FLATTEN(input => t.items) f;
┌───────────────────────────────────────────────────────────────────────────┐│ transaction_id │ customer_id │ purchased_item │ price │├─────────────────┼─────────────────┼───────────────────┼───────────────────┤│ 101 │ 1 │ coffee │ 2.5 ││ 101 │ 1 │ donut │ 1.2 ││ 102 │ 2 │ bagel │ 1.8 ││ 102 │ 2 │ muffin │ 2 ││ 103 │ 3 │ timbit_assortment │ 5 │└───────────────────────────────────────────────────────────────────────────┘
-- Find maximum, minimum, and average prices of the purchased itemsSELECT MAX(f.value:price::FLOAT) AS max_price, MIN(f.value:price::FLOAT) AS min_price, AVG(f.value:price::FLOAT) AS avg_priceFROM tim_hortons_transactions t, LATERAL FLATTEN(input => t.items) f;
┌───────────────────────────────────────────────────────────┐│ max_price │ min_price │ avg_price │├───────────────────┼───────────────────┼───────────────────┤│ 5 │ 1.2 │ 2.5 │└───────────────────────────────────────────────────────────┘