Using standard SQL (uncheck "Use legacy SQL" in the "Display Options" section of the user interface), you can express the query as:
SELECT event_dim.name as name, (SELECT value.int_value FROM UNNEST(event_dim.params) WHERE key = "productID") AS productID, (SELECT value.int_value FROM UNNEST(event_dim.params) WHERE key = "value") AS value FROM `dataset.mytable` AS t, t.event_dim AS event_dim;
Edit: Updated example to include int_value as part of value based on the comment below. The following is a self-sufficient example that also demonstrates the approach:
WITH T AS ( SELECT ARRAY_AGG(event_dim) AS event_dim FROM ( SELECT STRUCT( "foo" AS name, ARRAY<STRUCT<key STRING, value STRUCT<int_value INT64, string_value STRING>>>[ ("productID", (10, NULL)), ("value", (5, NULL)) ] AS params) AS event_dim UNION ALL SELECT STRUCT( "bar" AS name, ARRAY<STRUCT<key STRING, value STRUCT<int_value INT64, string_value STRING>>>[ ("productID", (13, NULL)), ("value", (42, NULL)) ] AS params) AS event_dim ) ) SELECT event_dim.name as name, (SELECT value.int_value FROM UNNEST(event_dim.params) WHERE key = "productID") AS productID, (SELECT value.int_value FROM UNNEST(event_dim.params) WHERE key = "value") AS value FROM T AS t, t.event_dim AS event_dim;
source share