复制Jinja中的case when语句



我想用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

最新更新