如何在JinjaSQL中循环遍历动态定义的列表生成目标SQL语句
问题根源
你之前的代码错误将agg_types列表通过replace处理为拼接字符串,传入cycler的是单个长文本而非列表元素,导致每次调用next()只会输出完整的拼接内容。同时原模板硬编码了求和字段profit_tot,无法匹配output中不同指标的计算需求。
修正后的完整实现
from jinjasql import JinjaSql j = JinjaSql(param_style='pyformat') QUERY_TEMPLATE = """ {% set agg_cycler = cycler(*agg_types) %} {% for o in output %} {% set metric = o.rsplit('_', 2)[0] %} ROUND(CAST(SUM(CASE WHEN agg_type = '{{ agg_cycler.next() | sqlsafe }}' THEN {{ metric | sqlsafe }} ELSE 0 END ) AS NUMERIC),2) AS {{ o | sqlsafe }}{% if not loop.last %},{% endif %} {% endfor %} """ params = { 'output': ['quantity_tot_1m', 'quantity_tot_3m', 'quantity_tot_6m', 'quantity_tot_12m', 'quantity_tot_full', 'cost_tot_1m', 'cost_tot_3m', 'cost_tot_6m', 'cost_tot_12m', 'cost_tot_full', 'selling_tot_1m', 'selling_tot_3m', 'selling_tot_6m', 'selling_tot_12m', 'selling_tot_full', 'profit_tot_1m', 'profit_tot_3m', 'profit_tot_6m', 'profit_tot_12m', 'profit_tot_full'], # 补充对应_full后缀的聚合类型,保证5个周期和output的5种后缀完全匹配 'agg_types': ['By SKU - 01 Month','By SKU - 03 Months','By SKU - 06 Months','By SKU - 12 Months', 'By SKU - Full Period'] } query, bind_params = j.prepare_query(QUERY_TEMPLATE, params) print(query)
核心改动说明
- 直接将
agg_types列表解包传入cycler,实现聚合类型的循环匹配,不需要额外做字符串替换操作 - 通过
rsplit('_', 2)[0]从输出列名中动态提取指标前缀(比如从quantity_tot_1m提取quantity_tot),替换原硬编码的profit_tot,保证计算逻辑和列名对应 - 通过
loop.last判断是否为最后一列,自动处理列之间的逗号分隔,避免SQL语法错误
内容的提问来源于stack exchange,提问作者Mengezi Dhlomo
相关产品推荐
相关产品推荐

