带有 dbt 宏的动态列的雪花“枢轴”

问题描述 投票:0回答:3

起始上下文:

  1. 有一个 dbt_utils“pivot”函数。这个问题与该功能有关。

  2. 一些讨论有关Snowflake内置PIVOT的局限性,即无法为此函数使用动态列和/或值。

example_model.sql

with pivot as (
    select * 
    from {{ ref('my_base_model') }}
        pivot( sum(VALUE) for KEY in ( 
        {{ dbt_utils.get_column_values(table=ref('my_base_model'), column='KEY') }} 
        ) )
)

select * from pivot

dbt 轻松解决了这个问题,除了一个小问题。当上面的代码被编译时(下面的代码块),它会生成一个 python 列表的值

[...]
当雪花期望更像一个元组时
(...)

with pivot as (
    select * 
    from DB.SCHEMA.my_base_model
        pivot( sum(VALUE) for KEY in ( ['value_1', 'value_2', 'value_3', 'value_4', 'value_5', 'value_6', 'value_7'] ) )
)

select * from pivot

我正在考虑使用类似

as_native
的东西将结果列表转换为元组,但到目前为止还没有成功。

dbt run
内的错误:

001003 (42000): SQL compilation error:
  syntax error line 5 at position 39 unexpected '['.
  syntax error line 5 at position 961 unexpected ']'.
  compiled SQL at target\run\dbtproject\models\staging\my_application
\my_base_model.sql
jinja2 snowflake-cloud-data-platform dbt
3个回答
1
投票

也许不是最好的答案,但有效的答案是:

pivot_model.sql

{% set pivot_cols = dbt_utils.get_column_values(table=ref('my_base_model'), column='KEY') %}

with pivot as (
    select * 
    from {{ ref('my_base_model') }}
        pivot( sum(VALUE) for KEY in (
            {% for pivot_col in pivot_cols %}
                '{{pivot_col}}'{% if not loop.last %}, {% endif%}
            {% endfor %}
         ))
)

select * from pivot

1
投票

** 更新 2 **: 由于 Jinja 不支持

tuple
作为过滤器,因此我们可以使用
join
代替:

with pivot as (
    select * 
    from {{ ref('my_base_model') }}
        pivot( sum(VALUE) for KEY in ( 
        {{ dbt_utils.get_column_values(table=ref('my_base_model'), column='KEY') | join(",") }} 
        )
)

select * from pivot

** 更新 1 **: 如果您想用

dbt
来做,让我们试试这个:

  1. dbt_utils.get_column_values
    的结果转换为
    tuple
with pivot as (
    select * 
    from {{ ref('my_base_model') }}
        pivot( sum(VALUE) for KEY in ( 
        {{ dbt_utils.get_column_values(table=ref('my_base_model'), column='KEY') | tuple }} 
        ) )
)

select * from pivot
  1. 您始终可以尝试在本地项目中创建一个自定义 dbt 宏,它是
    dbt_utils.get_column_values
    的副本并使用它:

原点获取列值

定制:

...
{%- set values = value_list['data'] | map(attribute=0) | tuple %}
...

** 起源 ** 请仔细查看pivot 文档

SELECT ...
FROM ...
   PIVOT ( <aggregate_function> ( <pivot_column> )
            FOR <value_column> IN ( <pivot_value_1> [ , <pivot_value_2> ... ] ) )

[ ... ]

它没有 [ ],这在您的查询中是不正确的

所以修复应该是:

with pivot as (
    select * 
    from DB.SCHEMA.my_base_model
        pivot( sum(VALUE) for KEY in ( 'value_1', 'value_2', 'value_3', 'value_4', 'value_5', 'value_6', 'value_7' ) )
)

select * from pivot

0
投票

Snowflake 现在支持使用 PIVOT IN 列表中的 ANY 关键字或子查询进行动态透视

select *
from performance_reviews
pivot (avg(rating) for skill in (ANY))

select *
from performance_reviews
pivot (avg(rating) for skill in (select skill from performance_reviews where rating > 4));

更多示例在这里: https://qosf.com/snowflake-support-for-ANY-keyword-in-the-PIVOT-IN-list.html

© www.soinside.com 2019 - 2024. All rights reserved.