How do I group by into struct in BigQuery?

Viewed 2452

I have the following data:

player_id level talent_id
1         1     a
1         2     b
1         3     c
2         1     d
2         2     e

And want to group by player_id and have rows as structs, with level values as struct field names:

player_id data
1         {_1 = a, _2 = b, _3 = c}
2         {_1 = d, _2 = e, _3 = null}

the level column is always from the set of {1, 2, 3} but some levels might be missing (null)

What I've got so far is aggregation by player_id and with attached array of results:

talents as (
  select
    p.player_id,
    array_agg(struct(p.level, p.talent_id)) as talents
  from source.player_talent p
  group by player_id
),

player_id data
1         [{1, a}, {2, b}, {3, c}]
2         {{1, d}, {2, e}]

now I need to map this array to a struct with fixed property names _1, _2, _3

1 Answers

This returns the expected results:

WITH Players AS (
  SELECT 1 AS player_id, 1 AS level, 'a' AS talent_id UNION ALL
  SELECT 1, 2, 'b' UNION ALL
  SELECT 1, 3, 'c' UNION ALL
  SELECT 2, 1, 'd' UNION ALL
  SELECT 2, 2, 'e'
)
SELECT
  player_id,
  STRUCT(
    MAX(IF(level = 1, talent_id, NULL)) AS _1,
    MAX(IF(level = 2, talent_id, NULL)) AS _2,
    MAX(IF(level = 3, talent_id, NULL)) AS _3) AS data
FROM Players
GROUP BY player_id

The technique here is known as pivoting (converting rows to columns).

Related