You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

dbt+BigQuery报错:不允许按STRUCT类型表达式分组问题排查

解决dbt + BigQuery 分组报错:Grouping by expressions of type STRUCT is not allowed

我是dbt和BigQuery新手,搭建了一个从3张表取数的简单数据管道。在BigQuery中直接运行的关联分组查询可正常得到结果,但通过dbt转换后执行,出现报错“Grouping by expressions of type STRUCT is not allowed”。怀疑dbt将status表转换为STRUCT类型,附上相关代码及配置:

原BigQuery查询

select sta.status, concat(dri.forename, ' ' ,dri.surname) driver_name, count(sta.status) as number_of_fails
    from `dts_staging_f1_data.results` res
    inner join `dts_staging_f1_data.status` sta on sta.statusId = res.statusId
    inner join `dts_staging_f1_data.drivers` dri on dri.driverId = res.driverId
    where res.statusId not in (1, 11, 12, 13, 14, 15, 16, 17, 18, 19, 45, 50, 128,53,55,58,88,111,112,113,114,115,116,117,118,119,120,122,123,124,125,127,133,134)
    group by sta.status, dri.forename, dri.surname
    having count(sta.status) > 1
    order by count(sta.status) desc, sta.status ;

dbt生成的查询

with results as (
    select statusId, driverId from `omitted-project-id`.`dts_staging_f1_data`.`results`
),
 ref_status as (
    select status,statusId from `omitted-project-id`.`dts_staging_f1_data`.`status`
),
drivers as (
    select driverId,forename, surname from `omitted-project-id`.`dts_staging_f1_data`.`drivers`
),

final as (
    select ref_status.status, concat(drivers.forename, ' ', drivers.surname) as driver_name, count(ref_status.status) as number_of_fails
    from results
    inner join ref_status using (statusId)
    inner join drivers using (driverId)
    where results.statusId not in (1, 11, 12, 13, 14, 15, 16, 17, 18, 19, 45, 50, 128,53,55,58,88,111,112,113,114,115,116,117,118,119,120,122,123,124,125,127,133,134)
    group by ref_status.status, drivers.forename, drivers.surname
    order by count(ref_status.status) desc, ref_status.status 
)

select * from final

models.yml配置

version: 2

sources:
  - name: src-bq-de-f1-project
    schema: dts_staging_f1_data
    tables: 
      - name: results
      - name: status
      - name: drivers

问题原因

报错的核心是**status是BigQuery的保留关键字**,直接引用ref_status.status时,BigQuery会误将其解析为STRUCT类型(而非字段),导致分组操作被禁止。

解决方法

方式1:给status字段起别名

在ref_status的CTE中将status重命名为非保留字,后续查询统一使用别名:

with results as (
    select statusId, driverId from `omitted-project-id`.`dts_staging_f1_data`.`results`
),
 ref_status as (
    select status as status_desc, statusId from `omitted-project-id`.`dts_staging_f1_data`.`status`
),
drivers as (
    select driverId,forename, surname from `omitted-project-id`.`dts_staging_f1_data`.`drivers`
),

final as (
    select ref_status.status_desc, concat(drivers.forename, ' ', drivers.surname) as driver_name, count(ref_status.status_desc) as number_of_fails
    from results
    inner join ref_status using (statusId)
    inner join drivers using (driverId)
    where results.statusId not in (1, 11, 12, 13, 14, 15, 16, 17, 18, 19, 45, 50, 128,53,55,58,88,111,112,113,114,115,116,117,118,119,120,122,123,124,125,127,133,134)
    group by ref_status.status_desc, drivers.forename, drivers.surname
    order by count(ref_status.status_desc) desc, ref_status.status_desc 
)

select * from final

方式2:用反引号包裹保留字字段

在所有引用status字段的地方加反引号,明确告知BigQuery这是字段名:

with results as (
    select statusId, driverId from `omitted-project-id`.`dts_staging_f1_data`.`results`
),
 ref_status as (
    select `status`, statusId from `omitted-project-id`.`dts_staging_f1_data`.`status`
),
drivers as (
    select driverId,forename, surname from `omitted-project-id`.`dts_staging_f1_data`.`drivers`
),

final as (
    select ref_status.`status`, concat(drivers.forename, ' ', drivers.surname) as driver_name, count(ref_status.`status`) as number_of_fails
    from results
    inner join ref_status using (statusId)
    inner join drivers using (driverId)
    where results.statusId not in (1, 11, 12, 13, 14, 15, 16, 17, 18, 19, 45, 50, 128,53,55,58,88,111,112,113,114,115,116,117,118,119,120,122,123,124,125,127,133,134)
    group by ref_status.`status`, drivers.forename, drivers.surname
    order by count(ref_status.`status`) desc, ref_status.`status` 
)

select * from final

额外建议

  • 尽量避免用BigQuery保留关键字作为表名或字段名,减少解析类问题
  • 在dbt中引用source时,使用{{ source('src-bq-de-f1-project', 'status') }}语法,dbt会自动处理保留字的反引号包裹:
ref_status as (
    select `status`, statusId from {{ source('src-bq-de-f1-project', 'status') }}
)

内容的提问来源于stack exchange,提问作者user4676827

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 19:39:17