Struct BigQuery结构聚合

Struct BigQuery结构聚合,struct,google-bigquery,aggregation,Struct,Google Bigquery,Aggregation,我正在BigQuery上处理一个ETL作业,试图在可能存在冲突源的地方协调数据。我首先使用array\u agg(distinct my\u column ignore nulls)找出需要对账的位置,然后我需要根据源对每列数据进行优先级排序 我想array\u agg(struct(data\u source,my\u column))并希望能够轻松提取给定列的首选源数据。但是,使用此方法,我无法将数据聚合为结构,而是将数据聚合为结构数组 考虑下面的简化示例,我更愿意从人力资源部获得职位,从食

我正在BigQuery上处理一个ETL作业,试图在可能存在冲突源的地方协调数据。我首先使用
array\u agg(distinct my\u column ignore nulls)
找出需要对账的位置,然后我需要根据源对每列数据进行优先级排序

我想
array\u agg(struct(data\u source,my\u column))
并希望能够轻松提取给定列的首选源数据。但是,使用此方法,我无法将数据聚合为结构,而是将数据聚合为结构数组

考虑下面的简化示例,我更愿意从人力资源部获得
职位
,从食堂获得
膳食

with data_set as (
    select 'John' as employee, 'Senior Manager' as job_title, 'vegan' as dietary_pref, 'HR' as source
    union all
    select 'John' as employee, 'Manager' as job_title, 'vegetarian' as dietary_pref, 'Canteen' as source
    union all
    select 'Mary' as employee, 'Marketing Director' as job_title, 'pescatarian' as dietary_pref, 'HR' as source
    union all
    select 'Mary' as employee, 'Marketing Manager' as job_title, 'gluten-free' as dietary_pref, 'Canteen' as source

)

select employee,
       array_agg(struct(source, job_title)) as job_title,
       array_agg(struct(source, dietary_pref)) as dietary_pref,
from data_set
group by employee
我为John获得的关于职位的数据如下:

鉴于我正在努力实现:
[{'HR':'高级经理','食堂':'经理'}]

有了struct输出,我希望可以使用
my_struct.my_preferred_source
轻松访问首选源代码。我希望在这个特殊情况下调用
job\u title.HR
dietary\u pref.食堂

因此,在这里的伪SQL中,我想我会:

select employee,
        AGGREGATE_JOB_TITLE_AS_STRUCT(source, job_title).HR  as job_title,
        AGGREGATE_DIETARY_PREF_AS_STRUCT(source, dietary_pref).Canteen as dietary_pref, 
from data_set group by employee
然后,输出将是:

我想帮你解决这个问题。也许这完全是错误的方法,但考虑到我处理的数据集更为复杂,我认为这将是首选方法(尽管失败了)

对其他选择持开放态度。请告知。谢谢

注意:我在Mikhail的回答之后编辑了这篇文章,该回答使用了一种与我预期略有不同的方法解决了我的问题,并在下面添加了更多关于我打算为每个员工使用单一结构的详细信息

select employee,
  array_agg(struct(source as job_source, job_title) order by if(source = 'HR', 1, 2) limit 1)[offset(0)].*,
  array_agg(struct(source as dietary_source, dietary_pref) order by if(source = 'HR', 2, 1) limit 1)[offset(0)].*
from data_set
group by employee                  
如果应用于问题中的样本数据,则输出为

更新:

下面用于澄清输出

select employee,
  array_agg(job_title order by if(source = 'HR', 1, 2) limit 1)[offset(0)] as job_title,
  array_agg(dietary_pref order by if(source = 'HR', 2, 1) limit 1)[offset(0)] as dietary_pref
from data_set
group by employee
有输出


谢谢米哈伊尔!永远在这里拯救这一天!因此,在您的解决方案中,这很好:您坚持使用结构数组。我还学习了(1)可以在数组_agg()中传递order by,以及(2)可以在order by中传递条件。顶部为了便于学习:有没有一种方法可以聚合一个结构而不是一个结构数组?最后,我希望能够输出job_title.HR以从HR源获取HR职务。这可行吗?如果是这样,怎么做?您的要求不清楚。我建议你提供一个很好的预期产出的例子(基于已经提供的输入数据样本)Hi Mikhail:在最初的帖子中,我写道“我为John获得的关于职位的数据是:[{'HR':'Senior Manager'},{'Mighter':'Manager'}],而我正在努力实现:[{'HR':'Senior Manager','Mighter':'Manager'}]。事实上,我所取得的成绩是错误的,事实上是[{“来源”:“人力资源”,“职务头衔”:“高级经理”},{“来源”:“食堂”:“经理”}]。但是,我试图将源名称作为键,将职务作为值。因此,目标描述正确,即我想要输出:[{'HR':'高级经理','食堂':'经理'}]仍然不清楚确切的输出是什么-至少对我来说根本不清楚!您可以提供预期输出的模式吗?我添加了一个伪代码,描述了我希望如何构建一些结构并调用结构键以及预期输出。我希望这能澄清,如果我的要求不清楚,很抱歉。也许,我问的是SQL不能做的事情。