带有 dbt 宏的动态列的 Snowflake "Pivot"
Snowflake "Pivot" for dynamic columns with dbt macro
起始上下文:
有一个dbt_utils“枢轴”功能。这个问题不与那个函数有关。
存在some discussion about the limitations of Snowflake's built-in PIVOT,即无法为此函数使用动态列and/or值。
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
也许不是最好的答案,但一个可行的答案是:
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
** 更新 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
来做,让我们试试这个:
- 将
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
- 您始终可以尝试创建自定义 dbt 宏,它是本地项目中
dbt_utils.get_column_values
的副本并使用它:
自定义:
...
{%- set values = value_list['data'] | map(attribute=0) | tuple %}
...
** 来源 **
请仔细看pivot doc.
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
起始上下文:
有一个dbt_utils“枢轴”功能。这个问题不与那个函数有关。
存在some discussion about the limitations of Snowflake's built-in PIVOT,即无法为此函数使用动态列and/or值。
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
也许不是最好的答案,但一个可行的答案是:
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
** 更新 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
来做,让我们试试这个:
- 将
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
- 您始终可以尝试创建自定义 dbt 宏,它是本地项目中
dbt_utils.get_column_values
的副本并使用它:
自定义:
...
{%- set values = value_list['data'] | map(attribute=0) | tuple %}
...
** 来源 ** 请仔细看pivot doc.
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