Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Escreve SQL otimizado para o stack Evolution (PostgreSQL primário) com boas práticas. Use quando precisar traduzir uma necessidade de dados em SQL, construir uma query com múltiplas CTEs, joins e agregações, otimizar uma query contra tabelas grandes, ou obter sintaxe específica para consultas no banco do Evo CRM, Evo AI, ou qualquer serviço do stack Evolution. Dialetos secundários disponíveis: Snowflake, BigQuery, MySQL, DuckDB.
.claude/skills/evolution-foundation-data-write-query/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-10 | ✗→✓ | ▲ Improved | 181% | 0% |
| case-19 | ✗→✓ | ▲ Improved | 553% | 0% |
| case-01 | ✓→✓ | = Same ✓ | 164% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 118% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 340% | 0% |
Escreve uma query SQL a partir de uma descrição em linguagem natural, otimizada para o dialeto PostgreSQL (stack padrão Evolution) e seguindo boas práticas.
/data-write-query <descrição do que você precisa consultar>Analisar a descrição do usuário para identificar:
Dialeto primário do workspace:
Dialetos secundários (se explicitamente solicitados):
Se o usuário não especificar, assumir PostgreSQL como padrão.
Se a fonte de dados estiver disponível via MCP ou CLI:
Queries de exploração de schema (PostgreSQL):
sql-- Listar todas as tabelas no schema SELECT table_name, table_type FROM information_schema.tables WHERE table_schema = 'public' ORDER BY table_name; -- Detalhes das colunas de uma tabela SELECT column_name, data_type, is_nullable, column_default FROM information_schema.columns WHERE table_name = 'nome_da_tabela' ORDER BY ordinal_position; -- Tamanho das tabelas SELECT relname AS tabela, pg_size_pretty(pg_total_relation_size(relid)) AS tamanho_total FROM pg_catalog.pg_statio_user_tables ORDER BY pg_total_relation_size(relid) DESC; -- Índices de uma tabela SELECT indexname, indexdef FROM pg_indexes WHERE tablename = 'nome_da_tabela';
Seguir estas boas práticas:
Estrutura:
novos_clientes_diarios, usuarios_ativos, receita_por_plano)Performance:
SELECT * em queries de produção — especificar apenas as colunas necessáriasEXISTS sobre IN para subconsultas com grandes conjuntos de resultadosLegibilidade:
a, b, c)Otimizações específicas do PostgreSQL:
sql-- Usar EXPLAIN ANALYZE para entender o plano de execução EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT) SELECT ...; -- Usar LIMIT + OFFSET para paginação SELECT * FROM tabela ORDER BY criado_em DESC LIMIT 50 OFFSET 0; -- Window functions eficientes no PostgreSQL SELECT cliente_id, valor, SUM(valor) OVER (PARTITION BY cliente_id ORDER BY data_pagamento) AS valor_acumulado, ROW_NUMBER() OVER (PARTITION BY cliente_id ORDER BY data_pagamento DESC) AS rn FROM pagamentos; -- DISTINCT ON (específico do PostgreSQL) — mais eficiente que ROW_NUMBER SELECT DISTINCT ON (cliente_id) cliente_id, plano, criado_em FROM assinaturas ORDER BY cliente_id, criado_em DESC; -- Funções de data no PostgreSQL DATE_TRUNC('month', criado_em) -- Início do mês EXTRACT(DOW FROM criado_em) -- Dia da semana (0=domingo) NOW() AT TIME ZONE 'America/Sao_Paulo' -- Hora atual em BRT criado_em AT TIME ZONE 'UTC' AT TIME ZONE 'America/Sao_Paulo' -- Converter para BRT INTERVAL '30 days' -- Subtração de intervalo DATE_PART('epoch', fim - inicio) -- Diferença em segundos -- JSON/JSONB (comum no stack Evolution) dados->>'campo' -- Extrair como texto dados->'campo' -- Extrair como JSON jsonb_array_elements(dados->'lista') -- Expandir array JSON dados @> '{"status": "active"}'::jsonb -- Contém (usa índice GIN) -- Array operations ANY(ARRAY['active', 'trial']) -- In array array_agg(campo ORDER BY data) -- Agregar em array unnest(tags) -- Expandir array em linhas
Padrões de query para as fontes do workspace:
sql-- Padrão: Análise de MRR mensal (típico para dados exportados do Stripe) WITH receita_mensal AS ( SELECT DATE_TRUNC('month', data_pagamento) AS mes, SUM(valor_cents) / 100.0 AS receita_total, COUNT(DISTINCT cliente_id) AS clientes_pagantes FROM pagamentos WHERE status = 'succeeded' AND data_pagamento >= NOW() - INTERVAL '12 months' GROUP BY 1 ), crescimento AS ( SELECT mes, receita_total, clientes_pagantes, LAG(receita_total) OVER (ORDER BY mes) AS receita_anterior, ROUND( (receita_total - LAG(receita_total) OVER (ORDER BY mes)) / NULLIF(LAG(receita_total) OVER (ORDER BY mes), 0) * 100, 2 ) AS crescimento_pct FROM receita_mensal ) SELECT * FROM crescimento ORDER BY mes; -- Padrão: Instâncias ativas com versão (típico para Licensing) WITH instancias_ativas AS ( SELECT instancia_id, versao, pais, criado_em, ultimo_ping FROM instancias WHERE ultimo_ping >= NOW() - INTERVAL '24 hours' AND status = 'active' ), por_versao AS ( SELECT versao, COUNT(*) AS total, COUNT(DISTINCT pais) AS paises_distintos FROM instancias_ativas GROUP BY 1 ) SELECT versao, total, paises_distintos, ROUND(total * 100.0 / SUM(total) OVER (), 2) AS percentual FROM por_versao ORDER BY total DESC; -- Padrão: Análise de funil (Evo CRM) WITH funil AS ( SELECT DATE_TRUNC('week', criado_em) AS semana, COUNT(*) FILTER (WHERE etapa = 'lead') AS leads, COUNT(*) FILTER (WHERE etapa = 'qualificado') AS qualificados, COUNT(*) FILTER (WHERE etapa = 'proposta') AS propostas, COUNT(*) FILTER (WHERE etapa = 'fechado_ganho') AS fechados FROM oportunidades WHERE criado_em >= NOW() - INTERVAL '90 days' GROUP BY 1 ) SELECT semana, leads, qualificados, propostas, fechados, ROUND(qualificados * 100.0 / NULLIF(leads, 0), 1) AS taxa_qualificacao, ROUND(fechados * 100.0 / NULLIF(leads, 0), 1) AS taxa_fechamento FROM funil ORDER BY semana; -- Padrão: Análise de cohort de retenção WITH cohorts AS ( SELECT cliente_id, DATE_TRUNC('month', primeira_assinatura) AS cohort_mes FROM clientes ), atividade_mensal AS ( SELECT DISTINCT cliente_id, DATE_TRUNC('month', data_evento) AS mes_ativo FROM eventos ), retencao AS ( SELECT c.cohort_mes, DATE_PART('month', AGE(a.mes_ativo, c.cohort_mes)) AS meses_depois, COUNT(DISTINCT c.cliente_id) AS clientes_retidos FROM cohorts c JOIN atividade_mensal a USING (cliente_id) WHERE a.mes_ativo >= c.cohort_mes GROUP BY 1, 2 ), tamanho_cohort AS ( SELECT cohort_mes, COUNT(DISTINCT cliente_id) AS tamanho FROM cohorts GROUP BY 1 ) SELECT r.cohort_mes, r.meses_depois, r.clientes_retidos, tc.tamanho AS tamanho_cohort, ROUND(r.clientes_retidos * 100.0 / tc.tamanho, 1) AS taxa_retencao FROM retencao r JOIN tamanho_cohort tc USING (cohort_mes) ORDER BY r.cohort_mes, r.meses_depois;
Fornecer:
Se a fonte de dados estiver disponível via skill, oferecer executar a query e analisar os resultados. Se o usuário preferir executar manualmente, a query está pronta para copiar e colar.
Agregação simples:
/data-write-query Contagem de assinaturas por plano nos últimos 30 diasAnálise complexa:
/data-write-query Análise de retenção por cohort — agrupar clientes pelo mês de assinatura, depois mostrar qual percentual ainda está ativo aos 1, 3, 6 e 12 mesesPerformance crítica:
/data-write-query Temos uma tabela de eventos com 500M de linhas particionada por data. Encontrar os 100 usuários com mais eventos nos últimos 7 dias com o tipo de evento mais recente de cada um.Com timezone:
/data-write-query Instâncias criadas esta semana, agrupadas por dia em BRT (America/Sao_Paulo)| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | pass→pass | 7,299 | 5,106 | -30% | 1 | 1 | 0% | 1,440 | 3,806 | +164% | 0 | 0 | — |
case-02 | pass→pass | 9,721 | 7,262 | -25% | 1 | 1 | 0% | 1,982 | 4,316 | +118% | 0 | 0 | — |
case-03 | pass→pass | 5,501 | 6,339 | +15% | 1 | 1 | 0% | 895 | 3,937 | +340% | 0 | 0 | — |
case-04 | pass→pass | 3,257 | 4,934 | +51% | 1 | 1 | 0% | 579 | 3,679 | +535% | 0 | 0 | — |
case-05 | pass→pass | 9,429 | 10,067 | +7% | 1 | 1 | 0% | 1,698 | 4,630 | +173% | 0 | 0 | — |
case-06 | pass→pass | 10,491 | 6,286 | -40% | 1 | 1 | 0% | 2,118 | 4,080 | +93% | 0 | 0 | — |
case-07 | pass→pass | 15,867 | 10,282 | -35% | 1 | 1 | 0% | 3,194 | 4,747 | +49% | 0 | 0 | — |
case-08 | pass→pass | 15,204 | 14,021 | -8% | 1 | 1 | 0% | 3,116 | 5,639 | +81% | 0 | 0 | — |
case-09 | pass→pass | 8,652 | 7,563 | -13% | 1 | 1 | 0% | 1,840 | 4,412 | +140% | 0 | 0 | — |
case-10 | fail→pass | 7,487 | 6,706 | -10% | 1 | 1 | 0% | 1,450 | 4,077 | +181% | 0 | 0 | — |
case-11 | pass→pass | 5,121 | 6,190 | +21% | 1 | 1 | 0% | 854 | 3,965 | +364% | 0 | 0 | — |
case-12 | pass→pass | 16,209 | 15,693 | -3% | 1 | 1 | 0% | 3,072 | 5,926 | +93% | 0 | 0 | — |
case-13 | pass→pass | 6,678 | 8,963 | +34% | 1 | 1 | 0% | 1,380 | 4,646 | +237% | 0 | 0 | — |
case-14 | pass→pass | 9,765 | 8,766 | -10% | 1 | 1 | 0% | 2,012 | 4,528 | +125% | 0 | 0 | — |
case-15 | fail→fail | 12,848 | 9,209 | -28% | 1 | 1 | 0% | 2,453 | 4,768 | +94% | 0 | 0 | — |
case-16 | pass→pass | 10,406 | 8,274 | -20% | 1 | 1 | 0% | 1,933 | 4,490 | +132% | 0 | 0 | — |
case-17 | pass→pass | 10,955 | 8,229 | -25% | 1 | 1 | 0% | 2,161 | 4,473 | +107% | 0 | 0 | — |
case-18 | pass→pass | 10,630 | 8,830 | -17% | 1 | 1 | 0% | 1,920 | 4,480 | +133% | 0 | 0 | — |
case-19 | fail→pass | 3,833 | 6,017 | +57% | 1 | 1 | 0% | 608 | 3,973 | +553% | 0 | 0 | — |
case-20 | pass→pass | 6,948 | 8,602 | +24% | 1 | 1 | 0% | 1,094 | 4,384 | +301% | 0 | 0 | — |
case-21 | pass→pass | 8,294 | 6,174 | -26% | 1 | 1 | 0% | 1,598 | 3,997 | +150% | 0 | 0 | — |
case-22 | pass→pass | 15,192 | 14,951 | -2% | 1 | 1 | 0% | 2,784 | 5,624 | +102% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +9 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.