I have a semistructured column that I would like to left lateral join after a cross join.
with t as ( select parse_json('{"1": 1, "2": 2}') as col ) , cartesian as ( select 1 as a union select 2 as a union select 3 as a ) select * from t cross join cartesian left join lateral flatten(input => t.col) as js on js.key::int = cartesian.a::int
In the above, I would expect the original cross join to expand the result count from 1 to 3; and the left lateral join should not reduce the number of rows returned.
The result I obtain is unexpected:
COL | A | SEQ | KEY | PATH | INDEX | VALUE | THIS |
---|---|---|---|---|---|---|---|
{ “1”: 1, “2”: 2 } |
1 | 1 | 1 | [‘1’] | NULL | 1 | { “1”: 1, “2”: 2 } |
{ “1”: 1, “2”: 2 } |
2 | 2 | 2 | [‘2’] | NULL | 2 | { “1”: 1, “2”: 2 } |
Am I crazy, or is the left
keyword not doing what it should here?
Advertisement
Answer
If I understood question correctly you are aiming for:
with t as ( select parse_json('{"1": 1, "2": 2}') as col ) , cartesian as ( select 1 as a union select 2 as a union select 3 as a ) select * from cartesian LEFT JOIN (SELECT * FROM t, TABLE(flatten(input => t.col))) as js ON js.key::int = cartesian.a::int;
Output:
Here the flattening of the JSON is perfomed inside inlined view and the result is joined using LEFT JOIN
to tally table.
Its a small difference, but in the above is t truly cross joined to cartesian?my intention was to have col populated in all rows above; by cross joining t to `cartesian
It could be adjusted:
with t as ( select parse_json('{"1": 1, "2": 2}') as col UNION ALL select parse_json('{"3": 3}') as col ) , cartesian as ( select 1 as a union select 2 as a union select 3 as a ) select * from cartesian CROSS JOIN t LEFT JOIN (SELECT * FROM t, TABLE(flatten(input => t.col))) as js ON js.key::int = cartesian.a::int AND t.col = js.this ORDER BY t.col, A;
Output: