- Created by Rosana Fagundes dos Santos Matos, last modified on Nov 19, 2025
You are viewing an old version of this page. View the current version.
Compare with Current View Page History
« Previous Version 3 Current »
Produto: maxInsights
1.0 Exemplos de SQL maxInsights
Este documento apresenta consultas SQL voltadas para geração de informações estratégicas, com foco em apoiar análises e decisões de negócio para clientes que utilizam o maxInsights.
1.1 Informações de atendimento
Visitas X Atendimentos
Relacionamento entre fato_atendimento e fato_visitas_realizadas
SELECT fa.sequencia_realizada_cliente as sequencia_realizada, fa.codigo_vendedor, fa.data_atendimento, fa.horainicio_atendimento AS inicio, fa.horafim_atendimento AS fim, fa.tempo_atendimento, fa.tempo_deslocamento, fa.codigo_cliente, fa.numero_pedido, fvr.id_rota, CASE WHEN dmj.id IS NULL THEN '' ELSE dmj.id || ' - ' || dmj.descricao END AS motivo, fvr.observacao, CASE WHEN fvr.id_rota IS NULL OR fvr.id_rota = '0' THEN 'N' ELSE 'S' END AS agendado, fvr.pdv FROM fato_atendimento fa INNER JOIN fato_visitas_realizadas fvr ON fvr."data" = fa.data_atendimento AND fvr.codigo_vendedor = fa.codigo_vendedor AND coalesce(fa.numero_pedido,0) = coalesce(fvr.numero_pedido,0) AND coalesce(fa.codigo_justificativa,'0') = coalesce(fvr.codigo_justificativa,'0') LEFT JOIN dim_motivo_justificativa dmj ON dmj.id = fvr.motivo WHERE fa.codigo_vendedor = '10' --CODIGO do VENDEDOR (RCA) AND fa.data_atendimento = DATE '2025-10-7' --DATA DO ATENDIMENTO ORDER BY data_atendimento, codigo_vendedor, sequencia_realizada |
1.2 Agendamentos e visitas
Dados detalhados com:
- Ordem de agendamento de visitas
- Ordem de execução das visitas
- Visitas avulsas (não agendadas)
WITH params AS ( SELECT DATE '2025-10-28' AS data_, --DATA DA VISITA CAST('999' AS TEXT) AS codigo_vendedor_ --CODIGO DO VENDEDOR ), /* ===================== [A] Recortes base ===================== */ fvr_cut AS ( -- visitas realizadas (já tipado) SELECT data::date AS data, hora AS hora_raw, codigo_cliente, CAST(REPLACE(id_rota, '.0', '') AS INT) AS id_rota, sequencia_realizada AS sequencia_realizada_original, codigo_vendedor, motivo, pdv, numero_pedido, codigo_justificativa, observacao FROM fato_visitas_realizadas CROSS JOIN params WHERE codigo_vendedor = params.codigo_vendedor_ AND data::date = params.data_ AND COALESCE(motivo, 0) <> 999 ), fpv_cut AS ( -- planejamento (já tipado) SELECT data::date AS data, '23:59:59' AS hora_pln_raw, codigo_cliente, CAST(id_rota AS INT) AS id_rota, sequencia, codigo_vendedor FROM fato_planejamento_visitas CROSS JOIN params WHERE codigo_vendedor = params.codigo_vendedor_ AND data::date = params.data_ ), /* ===================== [C] Visitas + join com fato_atendimento ===================== */ visitas AS ( SELECT fvr.data, fvr.codigo_cliente, CAST(fvr.id_rota AS VARCHAR) AS id_rota, TRY_CAST(fpv.sequencia AS INTEGER) AS sequencia_planejada, -- força tipo TRY_CAST(fa.sequencia_realizada_cliente AS INTEGER) AS sequencia_realizada, -- força tipo fvr.codigo_vendedor, CASE WHEN dmj.id IS NULL THEN '' ELSE dmj.descricao END AS motivo, fvr.pdv, fvr.numero_pedido, fvr.codigo_justificativa, fvr.observacao, fa.tempo_atendimento, fa.tempo_deslocamento FROM fato_atendimento fa INNER JOIN fvr_cut fvr ON fvr.data = fa.data_atendimento AND fvr.codigo_vendedor = fa.codigo_vendedor /* match por pedido/justificativa (exclusivo) */ AND coalesce(fa.numero_pedido,0) = coalesce(fvr.numero_pedido,0) AND coalesce(fa.codigo_justificativa,'0') = coalesce(fvr.codigo_justificativa,'0') LEFT JOIN fpv_cut fpv ON fpv.data = fvr.data AND fpv.id_rota = fvr.id_rota AND fpv.codigo_vendedor = fvr.codigo_vendedor AND fpv.codigo_cliente = fvr.codigo_cliente AND fpv.id_rota IS NOT NULL AND fpv.id_rota <> 0 LEFT JOIN dim_motivo_justificativa dmj ON dmj.id = fvr.motivo ), /* ===================== [E] SELECT final: bloco visitas ===================== */ bloco_visitas AS ( SELECT DISTINCT /* garanta tipos inteiros aqui também */ TRY_CAST(v.sequencia_planejada AS INTEGER) AS sequencia_planejada, TRY_CAST(v.sequencia_realizada AS INTEGER) AS sequencia_realizada, v.data, v.codigo_cliente, v.id_rota, v.codigo_vendedor, v.motivo, v.observacao, CASE WHEN v.id_rota IS NULL OR v.id_rota = '0' THEN 'N' ELSE 'S' END AS agendado, v.pdv, v.tempo_atendimento, v.tempo_deslocamento, v.numero_pedido FROM visitas v ), /* ===================== [E2] Planejado que não virou visita (ANTI-JOIN) ===================== */ planejado_base AS ( SELECT TRY_CAST(fpv.sequencia AS INTEGER) AS sequencia_planejada, -- inteiro CAST(0 AS INTEGER) AS sequencia_realizada, -- inteiro (zero) fpv.data AS data, fpv.codigo_cliente, CAST(fpv.id_rota AS VARCHAR) AS id_rota, fpv.codigo_vendedor, '' AS motivo, '' AS observacao, CASE WHEN fpv.id_rota IS NULL OR fpv.id_rota = 0 THEN 'N' ELSE 'S' END AS agendado, '' AS pdv, '00:00:00' AS tempo_atendimento, '00:00:00' AS tempo_deslocamento, 0 as numero_pedido FROM fpv_cut fpv ), exec_keys AS ( SELECT DISTINCT data, codigo_vendedor, codigo_cliente, id_rota FROM fvr_cut ), bloco_planejado_nao_exec AS ( SELECT pb.* FROM planejado_base pb LEFT JOIN exec_keys k ON k.data = pb.data AND k.codigo_vendedor = pb.codigo_vendedor AND k.codigo_cliente = pb.codigo_cliente AND CAST(k.id_rota AS VARCHAR) = pb.id_rota WHERE k.data IS NULL ) /* ===================== [F] Resultado unificado (com tipos alinhados) ===================== */ SELECT * FROM bloco_visitas UNION ALL SELECT * FROM bloco_planejado_nao_exec ORDER BY data, codigo_vendedor, sequencia_realizada |
1.3 Indicadores de agendamentos e visitas
Cálculo dos indicadores:
- total_planejadas - total de visitas planejada
- total_visitas_realizadas - total de visitas realizadas
- visitas_realizadas_das_planejadas - quantas visitas planejadas foram realizadas
- total_visitas_nao_realizadas - quantas visitas planejadas não foram realizadas
- cumprimento_agenda_visitas - percentual de visitas planejadas realizadas
- tempo_medio_visita - tempo médio de duração das visitas
- tempo_medio_deslocamento - tempo médio de deslocamento/percurso
- visitas_convertidas - total de visitas convertidas em pedidos / positivas
- taxa_conversao - percentual de conversão / positivação
- visitas_avulsas - total de visitas avulsas / não planejadas
- top_10_motivos - 10 motivos de não compra mais frequentes
WITH totalizador AS ( WITH params AS ( SELECT DATE '2025-10-28' AS data_, --DATA DA VISITA CAST('999' AS TEXT) AS codigo_vendedor_ --CODIGO DO VENDEDOR ), /* ===================== [A] Recortes base ===================== */ fvr_cut AS ( -- visitas realizadas (já tipado) SELECT data::date AS data, hora AS hora_raw, codigo_cliente, CAST(REPLACE(id_rota, '.0', '') AS INT) AS id_rota, sequencia_realizada AS sequencia_realizada_original, codigo_vendedor, motivo, pdv, numero_pedido, codigo_justificativa, observacao FROM fato_visitas_realizadas CROSS JOIN params WHERE codigo_vendedor = params.codigo_vendedor_ AND data::date = params.data_ AND COALESCE(motivo, 0) <> 999 ), fpv_cut AS ( -- planejamento (já tipado) SELECT data::date AS data, '23:59:59' AS hora_pln_raw, codigo_cliente, CAST(id_rota AS INT) AS id_rota, sequencia, codigo_vendedor FROM fato_planejamento_visitas CROSS JOIN params WHERE codigo_vendedor = params.codigo_vendedor_ AND data::date = params.data_ ), /* ===================== [C] Visitas + join com fato_atendimento ===================== */ visitas AS ( SELECT fvr.data, fvr.codigo_cliente, CAST(fvr.id_rota AS VARCHAR) AS id_rota, TRY_CAST(fpv.sequencia AS INTEGER) AS sequencia_planejada, -- força tipo TRY_CAST(fa.sequencia_realizada_cliente AS INTEGER) AS sequencia_realizada, -- força tipo fvr.codigo_vendedor, CASE WHEN dmj.id IS NULL THEN '' ELSE dmj.descricao END AS motivo, fvr.pdv, fvr.numero_pedido, fvr.codigo_justificativa, fvr.observacao, fa.tempo_atendimento, fa.tempo_deslocamento FROM fato_atendimento fa INNER JOIN fvr_cut fvr ON fvr.data = fa.data_atendimento AND fvr.codigo_vendedor = fa.codigo_vendedor /* match por pedido/justificativa (exclusivo) */ AND coalesce(fa.numero_pedido,0) = coalesce(fvr.numero_pedido,0) AND coalesce(fa.codigo_justificativa,'0') = coalesce(fvr.codigo_justificativa,'0') LEFT JOIN fpv_cut fpv ON fpv.data = fvr.data AND fpv.id_rota = fvr.id_rota AND fpv.codigo_vendedor = fvr.codigo_vendedor AND fpv.codigo_cliente = fvr.codigo_cliente AND fpv.id_rota IS NOT NULL AND fpv.id_rota <> 0 LEFT JOIN dim_motivo_justificativa dmj ON dmj.id = fvr.motivo ), /* ===================== [E] SELECT final: bloco visitas ===================== */ bloco_visitas AS ( SELECT DISTINCT /* garanta tipos inteiros aqui também */ TRY_CAST(v.sequencia_planejada AS INTEGER) AS sequencia_planejada, TRY_CAST(v.sequencia_realizada AS INTEGER) AS sequencia_realizada, v.data, v.codigo_cliente, v.id_rota, v.codigo_vendedor, v.motivo, v.observacao, CASE WHEN v.id_rota IS NULL OR v.id_rota = '0' THEN 'N' ELSE 'S' END AS agendado, v.pdv, v.tempo_atendimento, v.tempo_deslocamento, v.numero_pedido FROM visitas v ), /* ===================== [E2] Planejado que não virou visita (ANTI-JOIN) ===================== */ planejado_base AS ( SELECT TRY_CAST(fpv.sequencia AS INTEGER) AS sequencia_planejada, -- inteiro CAST(0 AS INTEGER) AS sequencia_realizada, -- inteiro (zero) fpv.data AS data, fpv.codigo_cliente, CAST(fpv.id_rota AS VARCHAR) AS id_rota, fpv.codigo_vendedor, '' AS motivo, '' AS observacao, CASE WHEN fpv.id_rota IS NULL OR fpv.id_rota = 0 THEN 'N' ELSE 'S' END AS agendado, '' AS pdv, '00:00:00' AS tempo_atendimento, '00:00:00' AS tempo_deslocamento, 0 as numero_pedido FROM fpv_cut fpv ), exec_keys AS ( SELECT DISTINCT data, codigo_vendedor, codigo_cliente, id_rota FROM fvr_cut ), bloco_planejado_nao_exec AS ( SELECT pb.* FROM planejado_base pb LEFT JOIN exec_keys k ON k.data = pb.data AND k.codigo_vendedor = pb.codigo_vendedor AND k.codigo_cliente = pb.codigo_cliente AND CAST(k.id_rota AS VARCHAR) = pb.id_rota WHERE k.data IS NULL ) /* ===================== [F] Resultado unificado (com tipos alinhados) ===================== */ SELECT * FROM bloco_visitas UNION ALL SELECT * FROM bloco_planejado_nao_exec ), -- ---------- util: transforma HH:MM:SS em segundos ---------- base AS ( SELECT t.*, CASE WHEN NULLIF(t.tempo_atendimento,'') IS NULL THEN NULL ELSE (CAST(SPLIT_PART(t.tempo_atendimento, ':', 1) AS INT) * 3600) + (CAST(SPLIT_PART(t.tempo_atendimento, ':', 2) AS INT) * 60) + CAST(SPLIT_PART(t.tempo_atendimento, ':', 3) AS INT) END AS tempo_atend_s, CASE WHEN NULLIF(t.tempo_deslocamento,'') IS NULL THEN NULL ELSE (CAST(SPLIT_PART(t.tempo_deslocamento, ':', 1) AS INT) * 3600) + (CAST(SPLIT_PART(t.tempo_deslocamento, ':', 2) AS INT) * 60) + CAST(SPLIT_PART(t.tempo_deslocamento, ':', 3) AS INT) END AS tempo_desl_s FROM totalizador t ), -- ---------- agregados principais (sem COUNT_IF) ---------- aggs AS ( SELECT COUNT(distinct sequencia_planejada) AS visitas_planejadas, COUNT(distinct sequencia_realizada) AS visitas_realizadas_total, COUNT(distinct CASE WHEN agendado = 'S' AND COALESCE(sequencia_realizada,0) > 0 THEN sequencia_planejada ELSE null END) AS visitas_realizadas_das_planejadas, COUNT(distinct CASE WHEN agendado = 'S' AND COALESCE(sequencia_realizada,0) = 0 THEN sequencia_planejada ELSE null END) AS visitas_nao_realizadas, --buscar cenário com planejadas não executadas AVG(NULLIF(tempo_atend_s, 0)) AS avg_visita_s, AVG(NULLIF(tempo_desl_s, 0)) AS avg_desloc_s, SUM(CASE WHEN COALESCE(sequencia_realizada,0) > 0 AND COALESCE(numero_pedido,0) > 0 THEN 1 ELSE 0 END) AS visitas_convertidas, COUNT(case when cast(sequencia_planejada as integer) is null and cast(sequencia_realizada as integer) is not null then sequencia_realizada else NULL end) AS visitas_avulsas FROM base ), -- ---------- KPIs já formatados ---------- kpis AS ( SELECT visitas_planejadas, visitas_realizadas_total, visitas_realizadas_das_planejadas, visitas_nao_realizadas, visitas_convertidas, visitas_avulsas, CASE WHEN visitas_planejadas = 0 THEN 0.0 ELSE ROUND((visitas_realizadas_das_planejadas::DECIMAL(18,6) / NULLIF(visitas_planejadas,0)) * 100, 2) END AS cumprimento_agenda_pct, CASE WHEN avg_visita_s IS NULL THEN '00:00:00' ELSE LPAD(CAST(FLOOR(avg_visita_s/3600) AS INT)::VARCHAR, 2, '0') || ':' || LPAD(CAST(FLOOR(MOD(avg_visita_s,3600)/60) AS INT)::VARCHAR, 2, '0') || ':' || LPAD(CAST(FLOOR(MOD(avg_visita_s,60)) AS INT)::VARCHAR, 2, '0') END AS tempo_medio_visita, CASE WHEN avg_desloc_s IS NULL THEN '00:00:00' ELSE LPAD(CAST(FLOOR(avg_desloc_s/3600) AS INT)::VARCHAR, 2, '0') || ':' || LPAD(CAST(FLOOR(MOD(avg_desloc_s,3600)/60) AS INT)::VARCHAR, 2, '0') || ':' || LPAD(CAST(FLOOR(MOD(avg_desloc_s,60)) AS INT)::VARCHAR, 2, '0') END AS tempo_medio_deslocamento, CASE WHEN visitas_realizadas_total = 0 THEN 0.0 ELSE ROUND((visitas_convertidas::DECIMAL(18,6) / NULLIF(visitas_realizadas_total,0)) * 100, 2) END AS taxa_conversao_pct FROM aggs ), -- ---------- principais justificativas de não venda ---------- justificativas AS ( SELECT LISTAGG(CASE WHEN NULLIF(TRIM(motivo),'') IS NULL THEN '[sem motivo]' ELSE TRIM(motivo) END, ', ') WITHIN GROUP (ORDER BY CASE WHEN NULLIF(TRIM(motivo),'') IS NULL THEN '[sem motivo]' ELSE TRIM(motivo) END) AS top_10_motivos, COUNT(*) AS qtde FROM base WHERE COALESCE(sequencia_realizada,0) > 0 AND COALESCE(numero_pedido,0) = 0 ORDER BY qtde DESC LIMIT 10 ) -- ==================== SAÍDA PRINCIPAL ==================== SELECT visitas_planejadas AS total_planejadas, visitas_realizadas_total AS total_visitas_realizadas, visitas_realizadas_das_planejadas, visitas_nao_realizadas AS total_visitas_nao_realizadas, cumprimento_agenda_pct AS cumprimento_agenda_visitas, tempo_medio_visita, tempo_medio_deslocamento, visitas_convertidas, taxa_conversao_pct AS taxa_conversao, visitas_avulsas, justificativas.top_10_motivos FROM kpis cross join justificativas |
1.4 Painel de auditória - visitas
Relacionamento entre as tabelas fato_visitas_realizadas, fato_atendimento, fato_eventos e fato_pedido_realizado, listadas de forma semelhante ao painel de auditoria.
WITH params AS ( SELECT DATE '2025-10-28' AS data_, --DATA DA VISITA cast('999' AS TEXT) AS codigo_vendedor_ --CODIGO DO VENDEDOR ), /* ===================== [A] Recortes base ===================== */ fvr_cut AS ( -- visitas realizadas (já tipado) SELECT data::date AS data, hora AS hora_raw, codigo_cliente, CAST(REPLACE(id_rota, '.0', '') AS int) AS id_rota, sequencia_realizada AS sequencia_realizada_original, codigo_vendedor, motivo, pdv, numero_pedido, codigo_justificativa, observacao FROM fato_visitas_realizadas CROSS JOIN params WHERE codigo_vendedor = params.codigo_vendedor_ AND data::date = params.data_ AND COALESCE(motivo, 0) <> 999 ), fpv_cut AS ( -- planejamento (já tipado) SELECT data::date AS data, '23:59:59' AS hora_pln_raw, codigo_cliente, CAST(id_rota AS int) AS id_rota, sequencia, codigo_vendedor FROM fato_planejamento_visitas CROSS JOIN params WHERE codigo_vendedor = params.codigo_vendedor_ AND data::date = params.data_ ), /* ===================== [B] Hora do atendimento (fonte preferencial) ===================== */ hv AS ( SELECT a.data_atendimento::date AS data, a.codigo_vendedor AS codigo_vendedor, a.codigo_cliente AS codigo_cliente, a.horainicio_atendimento AS hora_ini_raw, a.horafim_atendimento AS hora_fim_raw, a.tempo_atendimento AS tempo_atend_raw, a.numero_pedido AS numero_pedido, a.codigo_justificativa AS codigo_justificativa, a.sequencia_realizada_cliente AS sequencia_realizada, a.tempo_deslocamento FROM fato_atendimento a CROSS JOIN params WHERE a.data_atendimento::date = params.data_ AND a.codigo_vendedor = params.codigo_vendedor_ ), /* ===================== [C] Normalizadores de hora (robusto) ===================== */ visitas AS ( SELECT fvr.data, REGEXP_REPLACE(COALESCE(hv.hora_ini_raw, fvr.hora_raw), '[^0-9]', '') AS h_ini_clean, REGEXP_REPLACE(hv.hora_fim_raw, '[^0-9]', '') AS h_fim_clean, fvr.hora_raw, hv.hora_ini_raw, hv.hora_fim_raw, hv.tempo_atend_raw, hv.tempo_deslocamento, fvr.codigo_cliente, CAST(fvr.id_rota AS varchar) AS id_rota, fvr.sequencia_realizada_original, fpv.sequencia AS sequencia_planejada, hv.sequencia_realizada, fvr.codigo_vendedor, fvr.motivo, fvr.pdv, fvr.numero_pedido, fvr.codigo_justificativa, fvr.observacao FROM fvr_cut fvr LEFT JOIN fpv_cut fpv ON fpv.data = fvr.data AND fpv.id_rota = fvr.id_rota AND fpv.codigo_vendedor = fvr.codigo_vendedor AND fpv.codigo_cliente = fvr.codigo_cliente AND fpv.id_rota IS NOT NULL AND fpv.id_rota <> 0 LEFT JOIN hv ON hv.data = fvr.data AND hv.codigo_vendedor = fvr.codigo_vendedor AND hv.codigo_cliente = fvr.codigo_cliente AND coalesce(hv.numero_pedido, 0) = coalesce(fvr.numero_pedido, 0) AND coalesce(hv.codigo_justificativa, '0') = coalesce(fvr.codigo_justificativa, '0') ), /* ===================== [D] Distância p/ PDV ===================== */ distancia_cliente AS ( SELECT a.data_atendimento, a.codigo_cliente, a.codigo_vendedor, a.numero_pedido, a.codigo_justificativa, a.horainicio_atendimento AS inicio_raw, a.horafim_atendimento AS fim_raw, a.tempo_atendimento AS atend_raw FROM fato_atendimento a INNER JOIN dim_cliente c ON c.codigo_cliente = a.codigo_cliente LEFT JOIN fato_eventos e ON CAST(e.data_hora_evento_tz AS date) = a.data_atendimento AND e.codigo_cliente = a.codigo_cliente AND e.codigo_usuario = a.codigo_usuario WHERE coalesce(e.justificativa_nao_venda_codigovinculacao, '0') = coalesce(a.codigo_justificativa, '0') AND coalesce(e.numero_pedido_rca, 0) = coalesce(a.numero_pedido, 0) AND e.tipo_evento IN ('PEDIDO','JUSTIFICATIVANAOVENDA') ), /* ===================== [E] SELECT final: bloco visitas ===================== */ bloco_visitas AS ( SELECT DISTINCT dv.codigo_filial, v.sequencia_planejada, v.sequencia_realizada, to_char( to_timestamp(NULLIF(LPAD(v.h_ini_clean, 6, '0'), ''), 'HH24MISS'), 'HH24:MI:SS' ) AS inicio, to_char( to_timestamp(NULLIF(LPAD(v.h_fim_clean, 6, '0'), ''), 'HH24MISS'), 'HH24:MI:SS' ) AS fim, v.tempo_atend_raw AS atend, v.tempo_deslocamento as percurso, fpr.numped, fpr.numpederp, v.data, v.codigo_cliente, dc.razaosocial AS nome_cliente, dc.latitude, dc.longitude, v.id_rota, v.codigo_vendedor, v.motivo AS motivo_id, CASE WHEN dmj.id IS NULL THEN '' ELSE dmj.id || ' - ' || dmj.descricao END AS motivo, CAST(fpr.vlpedido AS NUMERIC(18, 2)) AS pedido, CAST(fpr.vlatend AS NUMERIC(18, 2)) AS atendido, CAST(fpr.vlbonific AS NUMERIC(18, 2)) AS bonificacao, v.observacao AS observacao, CASE WHEN v.id_rota IS NULL OR v.id_rota = '0' THEN 'N' ELSE 'S' END AS agendado, v.pdv FROM visitas v LEFT JOIN dim_cliente dc ON dc.codigo_cliente = v.codigo_cliente LEFT JOIN dim_motivo_justificativa dmj ON dmj.id = v.motivo LEFT JOIN fato_pedido_realizado fpr ON fpr.data_completa = v.data AND fpr.codigo_cliente = v.codigo_cliente AND fpr.codigo_vendedor = v.codigo_vendedor AND fpr.numped = v.numero_pedido AND v.motivo IS NULL LEFT JOIN dim_vendedores dv ON dv.codigo_vendedor = v.codigo_vendedor LEFT JOIN distancia_cliente dist ON dist.data_atendimento = v.data AND dist.codigo_vendedor = v.codigo_vendedor AND dist.codigo_cliente = v.codigo_cliente AND dist.numero_pedido = v.numero_pedido AND dist.codigo_justificativa= v.codigo_justificativa ), /* ===================== [E2] Planejado que não virou visita (ANTI-JOIN) ===================== */ planejado_base AS ( SELECT dv.codigo_filial, fpv.sequencia AS sequencia_planejada, 0 AS sequencia_realizada, '00:00:00' AS inicio, '00:00:00' AS fim, '00:00:00' AS atend, '00:00:00' AS percurso, 0 AS numped, 0 AS numpederp, fpv.data AS data, fpv.codigo_cliente, dc.razaosocial AS nome_cliente, '0' AS latitude, '0' AS longitude, CAST(fpv.id_rota AS varchar) AS id_rota, fpv.codigo_vendedor, 0 AS motivo_id, '' AS motivo, 0.0 AS pedido, 0.0 AS atendido, 0.0 AS bonificacao, '' AS observacao, CASE WHEN fpv.id_rota IS NULL OR fpv.id_rota = 0 THEN 'N' ELSE 'S' END AS agendado, '' AS pdv FROM fpv_cut fpv LEFT JOIN dim_cliente dc ON dc.codigo_cliente = fpv.codigo_cliente LEFT JOIN dim_vendedores dv ON dv.codigo_vendedor = fpv.codigo_vendedor ), exec_keys AS ( SELECT DISTINCT data, codigo_vendedor, codigo_cliente, id_rota FROM fvr_cut ), bloco_planejado_nao_exec AS ( SELECT pb.* FROM planejado_base pb LEFT JOIN exec_keys k ON k.data = pb.data AND k.codigo_vendedor= pb.codigo_vendedor AND k.codigo_cliente = pb.codigo_cliente AND CAST(k.id_rota AS varchar) = pb.id_rota WHERE k.data IS NULL ) /* ===================== [F] Resultado ===================== */ SELECT * FROM bloco_visitas UNION ALL SELECT * FROM bloco_planejado_nao_exec ORDER BY codigo_vendedor, data, sequencia_realizada; |
1.5 Painel de auditória - Pedidos, Justificativa de não venda e Venda avulsa
Classificar todas as visitas realizadas (pedidos ou justificativas) em três categorias: 'PEDIDO', 'JUSTIFICATIVANAOVENDA' ou 'VISITA AVULSA'. Utilizando apenas a fato_visitas_realizadas.
WITH ResultadosUnificados AS ( SELECT v.data, v.hora, v.codigo_cliente, v.codigo_vendedor,
-- Classifica o 'tipo_vinculo' com base na regra de negócio: CASE -- REGRA 1: Se o 'id_rota' é '0', significa que o cliente NÃO estava na agenda do vendedor. Portanto, é uma 'VISITA AVULSA'. WHEN v.id_rota = '0' THEN 'VISITA AVULSA'
-- REGRA 2: Se o 'id_rota' NÃO é '0' (estava na agenda) E tem um número de pedido, é um 'PEDIDO'. WHEN v.numero_pedido IS NOT NULL THEN 'PEDIDO' -- REGRA 3: Se o 'id_rota' NÃO é '0' (estava na agenda) E tem um motivo (de não venda), é uma 'JUSTIFICATIVANAOVENDA'. WHEN v.motivo IS NOT NULL THEN 'JUSTIFICATIVANAOVENDA'
-- Se não se encaixa em nada acima (ex: estava na agenda, mas não tem pedido nem motivo), trata como 'VISITA AVULSA'. ELSE 'VISITA AVULSA' END AS tipo_vinculo,
v.observacao, v.numero_pedido, v.motivo, v.codigo_justificativa FROM -- Usamos a tabela 'fato_visitas_realizadas' como base. fato_visitas_realizadas AS v ) -- Consulta final: Seleciona todos os dados da tabela SELECT ru.data, ru.hora, ru.codigo_cliente, ru.codigo_vendedor, ru.tipo_vinculo, ru.observacao, ru.numero_pedido, ru.motivo, ru.codigo_justificativa FROM ResultadosUnificados AS ru |
|---|
1.6 Painel de auditória - Pedidos, Justificativa de não venda e Venda avulsa utilizando FATO_EVENTOS
Classificar todas as visitas realizadas (pedidos ou justificativas) em três categorias: 'PEDIDO', 'JUSTIFICATIVANAOVENDA' ou 'VISITA AVULSA'. Utilizando fato_visitas_realizadas e fato_eventos.
WITH VisitasComEventoBruto AS (
-- Bloco 1: PEDIDOS (v.numero_pedido IS NOT NULL) Une a visita (v) com o evento bruto (e) que gerou o pedido SELECT v.data, v.hora, v.codigo_cliente, v.codigo_vendedor, v.id_rota, v.numero_pedido, v.motivo, v.codigo_justificativa, v.observacao, e.tipo_evento AS evento_bruto_encontrado -- Coluna de auditoria FROM fato_visitas_realizadas AS v LEFT JOIN fato_eventos AS e -- Condições do JOIN para PEDIDO: ON v.numero_pedido = e.numero_pedido_rca -- Chave principal do pedido AND e.tipo_evento = 'PEDIDO' -- Garante que é o evento de Pedido AND v.data = CAST(e.data_hora_evento_tz AS DATE) -- Otimização do join AND v.codigo_vendedor = e.codigo_vendedor -- Otimização do join WHERE v.numero_pedido IS NOT NULL -- Filtra apenas Pedidos da fato_visitas_realizadas
UNION ALL
-- Bloco 2: JUSTIFICATIVAS (v.numero_pedido IS NULL AND v.motivo IS NOT NULL) Une a visita (v) com o evento bruto (e) que gerou a justificativa SELECT v.data, v.hora, v.codigo_cliente, v.codigo_vendedor, v.id_rota, v.numero_pedido, v.motivo, v.codigo_justificativa, v.observacao, e.tipo_evento AS evento_bruto_encontrado -- Coluna de auditoria FROM fato_visitas_realizadas AS v LEFT JOIN fato_eventos AS e -- Condições do JOIN para JUSTIFICATIVA: ON v.codigo_justificativa = e.justificativa_nao_venda_codigovinculacao -- Chave da justificativa AND e.tipo_evento = 'JUSTIFICATIVANAOVENDA' -- Garante que é o evento de Justificativa AND v.data = CAST(e.data_hora_evento_tz AS DATE) AND v.codigo_vendedor = e.codigo_vendedor WHERE v.numero_pedido IS NULL AND v.motivo IS NOT NULL -- Filtra apenas Justificativas ), -- PASSO 2: Aplicar a classificação final (mesma lógica da consulta simples) ResultadosUnificados AS ( SELECT v.data, v.hora, v.codigo_cliente, v.codigo_vendedor,
-- Classificação IDÊNTICA à consulta simples (baseada apenas em 'v') CASE -- REGRA 1: Se o 'id_rota' é '0', é 'VISITA AVULSA'. WHEN v.id_rota = '0' THEN 'VISITA AVULSA'
-- REGRA 2: Se estava na agenda E tem pedido, é 'PEDIDO'. WHEN v.numero_pedido IS NOT NULL THEN 'PEDIDO' -- REGRA 3: Se estava na agenda E tem motivo, é 'JUSTIFICATIVANAOVENDA'. WHEN v.motivo IS NOT NULL THEN 'JUSTIFICATIVANAOVENDA'
ELSE 'VISITA AVULSA' END AS tipo_vinculo,
v.observacao, v.numero_pedido, v.motivo, v.codigo_justificativa, v.evento_bruto_encontrado -- Campo extra para auditoria FROM VisitasComEventoBruto AS v ) SELECT * FROM VisitasComEventoBruto; |
|---|
Notas de versão
Data | Versão anterior | Versão atual | Alteração | Motivo |
13/11/2025 | -- | 1.0 | Criação do dicionário com a inclusão dos SQLs: · Visitas X Atendimentos · Agendamentos e visitas · Indicadores de agendamentos · Painel de auditoria - visitas | Melhoria MAXINDV-698 |
14/11/2025 | 1.0 | 1.1 | Adição de exemplos SQL para eventos · Evento Pedido, Justificativa não Venda e Venda Avulsa o Realizado exemplo apenas fato_visitas_realizadas o Realizado exemplo com fato_eventos e fato_visitas_realizadas | Melhoria MAXINDV-625 |
Artigo criado por Thiago Oliveira
- No labels

