Этот ответ немного более многословен, но должен работать для ваших нужд. Я предпочитаю использовать ARRAY_AGG(STRUCT())
вместо STRUCT(ARRAY_AGG(),ARRAY_AGG())
, чтобы убедиться, что вы сохраняете отношения «Джордж - 13» и «Джейн - 14» (представьте, что вы добавили в свой список 14-летнего Джорджа, как бы вы сказали, какой ?).
WITH data as (
select '5a' as room_id, 'george' as name_student, 13 as age_student, 'Mr. Smith' as name_teacher, 43 as id_teacher
union all
select '5a' as room_id, 'george' as name_student, 13 as age_student, 'Mr. Climp' as name_teacher, 38 as id_teacher
union all
select '5a' as room_id, 'jane' as name_student, 14 as age_student , 'Mr. Smith' as name_teacher, 43 as id_teacher
union all
select '5a' as room_id, 'jane' as name_student, 14 as age_student, 'Mr. Climp' as name_teacher, 38 as id_teacher
),
students_distinct as (
select distinct room_id, name_student as name, age_student as age from data
),
students_agg as (
select room_id,array_agg(struct(name,age)) as student from students_distinct group by 1
),
teachers_distinct as (
select distinct room_id, name_teacher as name, id_teacher as id from data
),
teachers_agg as (
select room_id,array_agg(struct(name,id)) as teacher from teachers_distinct group by 1
)
select room_id, s.student, t.teacher
from students_agg s
inner join teachers_agg t using(room_id)