大家好,我有28个表(模型)要创建。我需要对这些表进行一些转换。因此,我决定使用宏不重复自己,也将有更多的转变在未来。我想从列中删除'%','$‘符号,并将其转换为浮动。什么是'%‘除以100。
我创建了这个模型:
SELECT
{{ clean_values('"Data"') }} AS "Data"
FROM
{{ source('mml_staging_eastor', 'DATAXIS_Development_indicators') }}我还创建了宏:
{% macro clean_values(value_column) -%}
{% do log(node, info=true) %}
{# {% set column_value = 'wme%mt' %} #}
{% set column_value = value_column %}
{% set col_val_list = value_column | list %}
{% if '%' in col_val_list %}
'{{ column_value | replace('%', '') }}'
{% elif '$' in col_val_list %}
'{{ column_value | replace('$', '') }}'
{% else %}
{{ col_val_list }}
{% endif %}
{%- endmacro %}宏在运行查询之前被编译(模板化)。这意味着数据不会在jinja templater中运行。当您{% set column_value = value_column %}时,您只是将一个值为value_column的字符串传递给jinja,而不是从具有该名称的字段中传递数据。
这是正确的,我将在我的模型中得到如下结果:“”、"D“、"a”、"t“、"a”、“”。
可以使用run_query宏将数据拉到jinja上下文中,但这很慢,而且容易出错。
*如果我使用注释行,那么将字符串'wme%mt'专用于变量,它运行得很好。
如何处理此操作以清除宏中的此列?
提前谢谢你!*
发布于 2022-08-02 17:01:04
我看到您找到了试图解释编译步骤和查询执行步骤之间的区别的my other answer。但是我认为你和其他人犯了同样的错误,你用jinja对表示列名的字符串进行操作,而不是使用SQL对列中的数据进行操作。
宏需要编写可以在数据库中执行的SQL。我无法从您的问题中完全看出$和%是否在数据或列名中,但假设前者(而且您使用的是雪花语或类似的方言),您的宏应该是这样的(请注意,%是一个SQL通配符,意思是“匹配任意数量的字符”,必须转义):
{% macro clean_values(column_name) -%}
case
when {{ column_name }} like '%^%' escape '^' -- number ending with %
then replace({{ column_name }}, '%', '')::float / 100.0
when {{ column_name }} like '$%' -- number starting with $
then replace({{ column_name }}, '$', '')::float
else {{ column_name }}::float
end
{% endmacro %}我在这里使用的是简单的cast操作符::,如果它不能将表达式转换为浮点数,它将抛出一个异常。如果列包含任何雪花不能转换的值,您可能更喜欢使用TRY_TO_DOUBLE,它将返回NULL而不是抛出异常。
https://stackoverflow.com/questions/73149551
复制相似问题