Ниже для BigQuery Standard SQL
#standardSQL
SELECT user_id,
ARRAY(
SELECT AS STRUCT ep.key AS key,
COALESCE(ep.value.string_value, CAST(ep.value.int_value AS STRING)) AS value
FROM UNNEST(ep) ep
) ep
FROM `project.dataset.table_name`
Вы можете проверить, поиграть с выше, используя пример данных из вашего вопроса, как в примере ниже
#standardSQL
WITH `project.dataset.table_name` AS (
SELECT 1 user_id, [STRUCT<key STRING, value STRUCT<string_value STRING, int_value INT64>>('origin', STRUCT('fcm', NULL))] ep UNION ALL
SELECT 2 user_id, [STRUCT<key STRING, value STRUCT<string_value STRING, int_value INT64>>('origin', STRUCT('fcm', NULL))] ep UNION ALL
SELECT 3 user_id, [STRUCT<key STRING, value STRUCT<string_value STRING, int_value INT64>>('screen', STRUCT(NULL, 4)),
STRUCT('origin', STRUCT('auto', NULL)),
STRUCT('id', STRUCT(NULL, 97))
] ep
)
SELECT user_id,
ARRAY(
SELECT AS STRUCT ep.key AS key,
COALESCE(ep.value.string_value, CAST(ep.value.int_value AS STRING)) AS value
FROM UNNEST(ep) ep
) ep
FROM `project.dataset.table_name`
с результатом
Row user_id ep.key ep.value
1 1 origin fcm
2 2 origin fcm
3 3 screen 4
origin auto
vid 97
Другой вариант может быть полезен в случае, если вам нужно сгруппировать все строки с одинаковым идентификатором пользователя.
#standardSQL
SELECT user_id,
ARRAY_AGG(STRUCT( ep.key AS key,
COALESCE(ep.value.string_value, CAST(ep.value.int_value AS STRING)) AS value
)) ep
FROM `project.dataset.table_name`, UNNEST(ep) ep
GROUP BY user_id
как в примере ниже с дополнительной строкой в данных выборки
#standardSQL
WITH `project.dataset.table_name` AS (
SELECT 1 user_id, [STRUCT<key STRING, value STRUCT<string_value STRING, int_value INT64>>('origin', STRUCT('fcm', NULL))] ep UNION ALL
SELECT 1 user_id, [STRUCT<key STRING, value STRUCT<string_value STRING, int_value INT64>>('origin2', STRUCT('fcm2', NULL))] ep UNION ALL
SELECT 2 user_id, [STRUCT<key STRING, value STRUCT<string_value STRING, int_value INT64>>('origin', STRUCT('fcm', NULL))] ep UNION ALL
SELECT 3 user_id, [STRUCT<key STRING, value STRUCT<string_value STRING, int_value INT64>>('screen', STRUCT(NULL, 4)),
STRUCT('origin', STRUCT('auto', NULL)),
STRUCT('id', STRUCT(NULL, 97))
] ep
)
SELECT user_id,
ARRAY_AGG(STRUCT( ep.key AS key,
COALESCE(ep.value.string_value, CAST(ep.value.int_value AS STRING)) AS value
)) ep
FROM `project.dataset.table_name`, UNNEST(ep) ep
GROUP BY user_id
с результатом
Row user_id ep.key ep.value
1 1 origin fcm
origin2 fcm2
2 2 origin fcm
3 3 screen 4
origin auto
id 97
если вы запустите первый вариант с теми же данными, вы получите результат ниже
Row user_id ep.key ep.value
1 1 origin fcm
2 1 origin2 fcm2
3 2 origin fcm
4 3 screen 4
origin auto
id 97