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

Oracle/MSSQL下dbt动态Pivot行转列实现求助

动态Pivot实现(Oracle/MSSQL)

Oracle 解决方案

Oracle原生Pivot需显式指定列名,针对超100个动态列的场景,需结合dbt宏+动态SQL实现:

步骤1:创建获取动态列名的宏

在dbt项目macros目录下新建get_pivot_columns.sql:

{% macro get_pivot_columns() %}
    select listagg('''' || adco_field_name || ''' as ' || adco_field_name, ', ') within group (order by adco_field_name)
    from (
        select distinct af.adco_field_name
        from {{ source('adco', 'sow_src_data') }} sd
        join {{ source('adco', 'src_field') }} sf on sd.src_field_id = sf.src_field_id
        join {{ source('adco', 'src_mapping') }} sm on sm.src_field_id = sf.src_field_id
        join {{ source('adco', 'adco_field') }} af on af.adco_field_id = sm.adco_field_id
        where effective_date = '2024-02-08'
    )
{% endmacro %}

步骤2:主模型中使用动态Pivot

{{ config(materialized='table') }}

declare
    v_pivot_cols varchar2(32767);
begin
    -- 获取动态列名
    select {{ get_pivot_columns() }} into v_pivot_cols from dual;

    -- 执行动态Pivot并生成目标表
    execute immediate '
        create table {{ this }} as
        with source_data as (
            select 
                sd.field_value,
                af.adco_field_name
            from 
                {{ source('adco', 'sow_src_data') }} sd
                join {{ source('adco', 'src_field') }} sf on sd.src_field_id = sf.src_field_id
                join {{ source('adco', 'src_mapping') }} sm on sm.src_field_id = sf.src_field_id
                join {{ source('adco', 'adco_field') }} af on af.adco_field_id = sm.adco_field_id
            where 
                effective_date = ''2024-02-08''
        )
        select *
        from source_data
        pivot (
            max(field_value) for adco_field_name in (' || v_pivot_cols || ')
        )
    ';
end;
/

MSSQL 解决方案

MSSQL可通过STRING_AGG生成动态列名,结合动态SQL实现:

主模型代码

{{ config(materialized='table') }}

declare @pivot_cols nvarchar(max);
declare @sql nvarchar(max);

-- 获取动态列名
select @pivot_cols = string_agg(quotename(adco_field_name), ', ')
from (
    select distinct af.adco_field_name
    from {{ source('adco', 'sow_src_data') }} sd
    join {{ source('adco', 'src_field') }} sf on sd.src_field_id = sf.src_field_id
    join {{ source('adco', 'src_mapping') }} sm on sm.src_field_id = sf.src_field_id
    join {{ source('adco', 'adco_field') }} af on af.adco_field_id = sm.adco_field_id
    where effective_date = '2024-02-08'
) as cols;

-- 拼接并执行动态SQL
set @sql = N'
    with source_data as (
        select 
            sd.field_value,
            af.adco_field_name
        from 
            ' + {{ source('adco', 'sow_src_data') }} + N' sd
            join ' + {{ source('adco', 'src_field') }} + N' sf on sd.src_field_id = sf.src_field_id
            join ' + {{ source('adco', 'src_mapping') }} + N' sm on sm.src_field_id = sf.src_field_id
            join ' + {{ source('adco', 'adco_field') }} + N' af on af.adco_field_id = sm.adco_field_id
        where 
            effective_date = ''2024-02-08''
    )
    select * into {{ this }}
    from source_data
    pivot (
        max(field_value) for adco_field_name in (' + @pivot_cols + N')
    ) as pvt;
';

exec sp_executesql @sql;

关键说明

  • 两个方案均使用max(field_value)聚合函数,因Pivot必须配合聚合操作;若adco_field_name唯一,max/min/first结果一致
  • 动态列名通过子查询获取去重后的adco_field_name,避免重复列
  • dbt的{{ this }}变量会自动替换为当前模型的目标表名

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 19:50:05