I have a table in Snowflake that looks something like this:
+------+------+------+------------------------------------------------------------------+
| Col1 | Col2 | Col3 | Col4 |
+------+------+------+------------------------------------------------------------------+
| 1 | foo | 32 | [{"id":"1", "category":"black"}] |
| 2 | bar | 22 | [{"id":"1", "category":"black"}, {"id":"4", "category":"white"}] |
| 3 | smeg | 2 | null |
+------+------+------+------------------------------------------------------------------+
I would like to transform the data into another table that looks like this:
+------+------+------+------+----------+
| Col1 | Col2 | Col3 | id | category |
+------+------+------+------+----------+
| 1 | foo | 32 | 1 | black |
| 2 | bar | 22 | 1 | black |
| 2 | bar | 22 | 4 | white |
| 3 | smeg | 2 | null | null |
+------+------+------+------+----------+
I've done this in SQL Server before using JSON_VALUE
and OPENJSON
but I am having trouble trying to find a Snowflake equivalent.
A correction to the above answer, Nulls need to be explicitly handled for category.
Lateral flatten alone would not consider NULLs, you can use OUTER => TRUE
or use UNION
with condition WHERE Col4 IS NULL
.
If FALSE, any input rows that cannot be expanded, either because they cannot be accessed in the path or because they have zero fields or entries, are completely omitted from the output.
If TRUE, exactly one row is generated for zero-row expansions (with NULL in the KEY, INDEX, and VALUE columns)
SELECT
col1,col2,col3,flatten.value:id::STRING AS id,
flatten.value:category::STRING AS category
FROM
test1 t,
LATERAL FLATTEN(input => t.col4,OUTER => TRUE) flatten
;
Output