如何使用dbt union_relations宏重定义列并计算含VAT成本?
实现方法
最直接的方式是用CTE(公共表表达式)包裹union_relations的结果,再对合并后的数据进行列的重定义和计算,具体步骤如下:
方法一:使用dbt_utils.star宏简化列选择
如果两个源视图的列结构一致(除了需要处理的costs列),可以用star宏快速选择所有列并排除costs,再手动添加重命名和计算后的列:
WITH unioned_data AS ( {{ dbt_utils.union_relations( relations=[ ref('ADS.ALL_ADVERTISEMENTS_V'), ref('ADS.ALL_OOH_V'), ], exclude=['_DBT_SOURCE_RELATION'] ) }} ) SELECT {{ dbt_utils.star(from=ref('ADS.ALL_ADVERTISEMENTS_V'), except=['costs']) }}, costs AS costs_no_vat, costs * 1.077 AS costs_vat FROM unioned_data
补充说明:
dbt_utils.star(from=..., except=['costs'])会自动选择源视图中除costs外的所有列,避免手动列写大量字段- 如果两个源视图的
costs列类型不一致(比如一个是INT、一个是FLOAT),可以在union_relations中添加column_override参数统一类型:{{ dbt_utils.union_relations( relations=[ ref('ADS.ALL_ADVERTISEMENTS_V'), ref('ADS.ALL_OOH_V'), ], exclude=['_DBT_SOURCE_RELATION'], column_override={'costs': 'FLOAT'} ) }}
方法二:手动列写所有字段
如果源视图列结构差异较大,或者需要更精细的控制,直接手动列出所有字段,替换costs的处理逻辑:
WITH unioned_data AS ( {{ dbt_utils.union_relations( relations=[ ref('ADS.ALL_ADVERTISEMENTS_V'), ref('ADS.ALL_OOH_V'), ], exclude=['_DBT_SOURCE_RELATION'] ) }} ) SELECT -- 替换为实际的其他列名 ad_id, campaign_name, start_date, end_date, -- 处理costs列 costs AS costs_no_vat, costs * 1.077 AS costs_vat FROM unioned_data
核心逻辑:
通过CTE先完成多视图的union操作,再在后续的SELECT语句中对costs列进行重命名和算术计算,既保留了union_relations的便捷性,又实现了自定义的列转换需求。
内容的提问来源于stack exchange,提问作者Guido
相关产品推荐
相关产品推荐

