Skip to content

Instantly share code, notes, and snippets.

@pagueru
Created August 15, 2025 01:10
Show Gist options
  • Save pagueru/a72e089d411b2654a0ddf7b22a20c1b1 to your computer and use it in GitHub Desktop.
Save pagueru/a72e089d411b2654a0ddf7b22a20c1b1 to your computer and use it in GitHub Desktop.
description
Reformata scripts SQL/dbt seguindo padrão de estilo específico sem alterar funcionalidades

PROMPT DE FORMATAÇÃO SQL/DBT

Reformate o script SQL fornecido seguindo EXATAMENTE o mesmo padrão de estilo do exemplo de contexto abaixo. Não adicione ou remova funcionalidades - apenas aplique a formatação e estrutura de estilo.

REGRAS DE FORMATAÇÃO:

  • Indentação: 4 espaços
  • Vírgulas: Sempre à esquerda nas listas de campos
  • Aliases: Sempre usar as
  • CTEs: Nomes descritivos em português com snake_case
  • Comentários: Em português usando --
  • Espaçamento: Linha em branco entre seções principais
  • Quebras de linha: Cada campo do SELECT em linha separada
  • Keywords: Minúsculas (select, from, where, etc.)
  • Estrutura: Seguir exatamente a organização do exemplo
  • Final: Sempre um select * from tabela na mesma linha
  • WHERE: Sempre use where 1=1 com linha em branco antes e depois, condições adicionais com and -FROM: A tabela deve sempre ficar na mesma linha do from, sem quebra de linha

CONTEXTO DE REFERÊNCIA - EXEMPLO DE ESTILO:

{{
    config(
        materialized='incremental',
        partition_by={
            "field": "created_date",
            "data_type": "date",
            "granularity": "day"
        },
        cluster_by=["customer_id", "product_category", "region"],
        incremental_strategy='merge',
        unique_key='transaction_id',
        on_schema_change='fail',
        pre_hook="{{ log('Iniciando processamento do modelo sales_transactions_incremental', info=True) }}",
        post_hook=[
            "{{ log('Modelo processado com sucesso', info=True) }}",
            "CALL `{{ target.project }}`.{{ target.dataset }}.update_stats_procedure()"
        ],
        tags=['sales', 'incremental', 'daily'],
        meta={
            'owner': 'data-team',
            'description': 'Modelo incremental para transações de vendas com particionamento e clusterização',
            'refresh_frequency': 'daily'
        }
    )
}}

-- Definição de variáveis Jinja
{%- set max_days_back = var('max_days_back', 7) -%}
{%- set target_currency = var('target_currency', 'USD') -%}
{%- set regions_to_include = var('regions_to_include', ['North', 'South', 'East', 'West']) -%}

-- Macro personalizada para formatação de moeda
{%- macro format_currency(column_name, currency='USD') -%}
    round({{ column_name }}, 2) as {{ column_name }}_formatted,
    concat('{{ currency }} ', format('%.2f', {{ column_name }})) as {{ column_name }}_display
{%- endmacro -%}

-- Macro para calcular percentil
{%- macro calculate_percentile(column_name, percentile=0.5) -%}
    percentile_cont({{ column_name }}, {{ percentile }}) over (
        partition by date_trunc(created_date, month)
    ) as {{ column_name }}_p{{ (percentile * 100)|int }}
{%- endmacro -%}

with source_data as (

    select
         transaction_id
        ,customer_id
        ,product_id
        ,quantity
        ,unit_price
        ,discount_percentage
        ,region
        ,sales_channel
        ,created_timestamp
        ,updated_timestamp

        -- Conversões de data para particionamento
        ,date(created_timestamp) as created_date
        ,extract(year from created_timestamp) as created_year
        ,extract(month from created_timestamp) as created_month
        ,extract(dayofweek from created_timestamp) as created_day_of_week


    from {{ source('raw_data', 'sales_transactions') }}

    where 1=1

    -- Lógica incremental com filtro de data
    {% if is_incremental() %}
        and date(updated_timestamp) >= (
            select coalesce(max(date(last_updated)), date_sub(current_date(), interval {{ max_days_back }} day))
            from {{ this }}
        )
    {% else %}
        and date(created_timestamp) >= date_sub(current_date(), interval 365 day)
    {% endif %}

    -- Filtro por regiões configuráveis
    and region in (
        {%- for region in regions_to_include %}
            '{{ region }}'
            {%- if not loop.last -%},{%- endif %}
        {%- endfor %}
    )

)

,customer_enriched as (

    select
         source_data.*
        ,dim_customers.customer_name
        ,dim_customers.customer_segment
        ,dim_customers.customer_tier
        ,dim_customers.registration_date as customer_registration_date

        -- Cálculo de tempo como cliente
        ,date_diff(source_data.created_date, date(dim_customers.registration_date), day) as days_as_customer

    from source_data

    left join {{ ref('dim_customers') }} as dim_customers
        on source_data.customer_id = dim_customers.customer_id

)

,product_enriched as (

    select
         customer_enriched.*
        ,dim_products.product_name
        ,dim_products.product_category
        ,dim_products.product_subcategory
        ,dim_products.brand
        ,dim_products.cost_price

        -- Cálculo de margem
        ,safe_divide((customer_enriched.unit_price - dim_products.cost_price), customer_enriched.unit_price) * 100 as margin_percentage

    from customer_enriched

    left join {{ ref('dim_products') }} as dim_products
        on customer_enriched.product_id = dim_products.product_id

)

,business_logic as (

    select
        *

        -- Cálculos financeiros
        ,quantity * unit_price as gross_amount
        ,quantity * unit_price * (1 - discount_percentage/100) as net_amount
        ,quantity * cost_price as cost_amount

        -- Aplicação de macro personalizada para formatação
        ,{{ format_currency('quantity * unit_price') }}

        -- Cálculo de percentis usando macro
        ,{{ calculate_percentile('quantity * unit_price', 0.5) }}
        ,{{ calculate_percentile('quantity * unit_price', 0.9) }}

        -- Classificações condicionais usando Jinja
        ,case
            when quantity * unit_price >= 1000 then 'High Value'
            when quantity * unit_price >= 500 then 'Medium Value'
            else 'Low Value'
        end as transaction_tier

        -- Flags baseadas em lógica de negócio
        {% for channel in ['online', 'retail', 'wholesale'] %}
        ,case when lower(sales_channel) = '{{ channel }}' then true else false end as is_{{ channel }}_sale
        {% endfor %}

        -- Indicadores temporais
        ,case
            when extract(dayofweek from created_date) in (1, 7) then true
            else false
        end as is_weekend_sale

        ,case
            when extract(hour from created_timestamp) between 9 and 17 then 'Business Hours'
            when extract(hour from created_timestamp) between 18 and 22 then 'Evening'
            else 'Night/Early Morning'
        end as time_period

    from product_enriched

    where 1=1

    and quantity > 0
    and unit_price > 0
    and discount_percentage between 0 and 100

    -- Validações de qualidade de dados usando Jinja
    {% if target.name == 'prod' %}
    and customer_id is not null
    and product_id is not null
    {% endif %}

)

,final_transformations as (

    select
        *

        -- Cálculos de janela temporal
        ,avg(net_amount) over (
            partition by customer_id
            order by created_timestamp
            rows between 2 preceding and current row
        ) as customer_avg_last_3_transactions

        ,row_number() over (
            partition by customer_id
            order by created_timestamp desc
        ) as customer_transaction_rank,

        -- Flags de primeira/última transação
        ,case
            when row_number() over (
                partition by customer_id
                order by created_timestamp asc
            ) = 1 then true
            else false
        end as is_first_transaction

        -- Timestamp de processamento
        ,current_timestamp() as last_updated
        ,'{{ run_started_at }}' as dbt_run_timestamp
        ,'{{ invocation_id }}' as dbt_invocation_id

    from business_logic

)

select * from final_transformations

INSTRUÇÕES:

  1. Aplique APENAS o estilo de formatação do exemplo acima
  2. Preserve toda a lógica e funcionalidades do script original
  3. Mantenha a mesma estrutura organizacional (config, variáveis, macros, CTEs)
  4. Use exatamente os mesmos padrões de indentação, quebras de linha e espaçamento
  5. Não adicione nem remova funcionalidades, apenas reformate o estilo

RESPONDA APENAS COM O SCRIPT REFORMATADO.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment