Let's say I have a row with a basic string array and a want to filter by an element in the array, I can use the pattern as below:
with members as (
select 'Bob' AS name, ['Running', 'Piano'] AS hobbies union all
select 'Derek', ['Cooking']
) select name, hobbies from members, unnest(hobbies) as hobby where hobby = 'Piano'
How would I do the same thing with a struct within the top-level array, for example to get all items with members.hobbies = 'Guitar' in the below?
-- members.hobbies = 'Guitar'
with teams as (
select 'Cubs' AS name, [STRUCT<name STRING, hobbies ARRAY<STRING>>('Derek', ['Guitar', 'Cooking'])] as members union all
select 'Jaguars', [('Bob', ['Running', 'Piano']), ('Sammy', ['Sailing'])]
)
select t.name, members, y from teams t, unnest(members) as y;
My best attempt is the pretty hack-ish:
-- members.hobbies = 'Guitar'
with teams as (
select 'Cubs' AS name, [STRUCT<name STRING, hobbies ARRAY<STRING>>('Derek', ['Guitar', 'Cooking'])] as members union all
select 'Jaguars', [('Bob', ['Running', 'Piano']), ('Sammy', ['Sailing'])]
) , m1 as (select t.*, hobbies from teams as t, unnest(members) as m_unnest)
select m1.name, m1.members from m1, unnest(hobbies) as h where h='Guitar'


hinstead of the structure?[{[{...I just find it very difficult to figure out how to traverse STRUCTs that contain an array in it (or an array that contains a struct in it).table.column.object_element_nameto access a specific element. If you have an array, you need to unnest it to translate to multiple rows. If the array elements are then objects, you can use the same syntax to access its elements, if the array elements are arrays, you can unnest them again. Ad infinitum. It's a bit clunky, but sql wasn't designed for nested structures, that's a bespoke retrofit by Google.select * from teams where 'Guitar' IN UNNEST(members.hobbies);is not enough?