我想用dbt中的jinja块复制一个简单的case-when语句。我怎样才能做到这一点呢?
下面是我的声明:
CASE status
WHEN 0 THEN 'pending'
WHEN 1 THEN 'ordered'
WHEN 2 THEN 'shipped'
WHEN 3 THEN 'received'
WHEN 4 THEN 'delivered'
ELSE NULL
END as status_mapping
您有几个选择。首先,可以在数组或字典中定义映射(如果id不是序列),并循环遍历它以生成完整的case语句:
{% set statuses = ['pending', 'ordered', 'shipped', 'received', 'delivered'] %}
CASE STATUS
{% for status in statuses %}
WHEN {{ loop.index - 1 }} THEN '{{ status }}'
{% endfor %}
ELSE NULL END STATUS_MAPPING
另一种选择是将映射放入CSV中,将其作为DBT (https://docs.getdbt.com/docs/build/seeds)中的种子数据文件加载,然后将种子数据作为ref
连接。
创建名为status_mappings.csv
的文件:
status_code,status
0,pending
1,ordered
2,shipped
3,received
4,delivered
运行dbt seed
,然后添加
WITH STATUS_MAPPINGS AS (
SELECT * FROM {{ ref('status_mappings') }}
}
SELECT S.STATUS
FROM MY_TABLE T1
JOIN STATUS_MAPPINGS SM ON T1.STATUS_CODE = SM.STATUS_CODE
您可以使用宏在不同的查询中插入可重用的SQL片段,这可能是您想要这样做的一个原因。
你可以这样定义宏:
-- yourproject/macros/status_mapping.sql
{% macro status_mapping(status) %}
CASE {{ status }}
WHEN 0 THEN 'pending'
WHEN 1 THEN 'ordered'
WHEN 2 THEN 'shipped'
WHEN 3 THEN 'received'
WHEN 4 THEN 'delivered'
ELSE NULL
END
{% endmacro %}
(我保持定义的灵活性)
…并在模型中调用它,例如:
-- yourproject/models/base/base__orders.sql
SELECT
order_id,
status_code,
{{ status_mapping('status_code') }} AS status
FROM
{{ source('your_dataset', 'orders') }}
注意在字段名周围使用引号,与下面两行内置source
宏相同。通过将字段名作为宏参数而不是硬编码(并在宏之外保留别名AS status
),您可以在将来灵活地更改内容。
当您运行DBT时,它将被编译为如下内容:
SELECT
order_id,
status_code,
CASE status_code
WHEN 0 THEN 'pending'
WHEN 1 THEN 'ordered'
WHEN 2 THEN 'shipped'
WHEN 3 THEN 'received'
WHEN 4 THEN 'delivered'
ELSE NULL
END AS status
FROM
your_dataset.orders