Atribuição e métricas de teste A/B
Associando a atribuição do experimento aos resultados e calculando métricas por variante.
Atribuição e métricas de teste A/B é uma aula grátis de Coding Interview Prep no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Coding Interview Prep, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Coding Interview Prep inclui 4 aulas no total.
O que uma pergunta sobre teste A/B avalia
As perguntas sobre testes A/B verificam se você consegue associar corretamente a atribuição do experimento aos resultados e calcular uma métrica limpa por variante.
A armadilha quase sempre está na junção: contar resultados de usuários que nunca foram incluídos no experimento ou contar duas vezes usuários atribuídos duas vezes. Faça a junção da atribuição corretamente e as métricas serão uma aritmética simples.
As duas tabelas recebidas
Espere uma tabela de atribuições e uma tabela de resultados:
assignments(user_id, variant, assigned_at), em que variant é 'controle' ou 'tratamento'.orders(user_id, order_id, amount, created_at)ou uma tabela genérica de eventos.
A atribuição é a fonte de verdade sobre quem participa do experimento. Só conte os resultados se o usuário aparecer na atribuição.
CREATE TABLE assignments (
user_id INT,
variant VARCHAR(20),
assigned_at TIMESTAMP
);
CREATE TABLE orders (
user_id INT,
order_id INT,
amount NUMERIC,
created_at TIMESTAMP
);Comece pela atribuição, LEFT JOIN resultados
A regra fundamental é: use a tabela de atribuições como base e faça LEFT JOIN com os resultados. Isso mantém os usuários incluídos no experimento que nunca converteram, algo necessário para obter um denominador honesto.
Um INNER JOIN descartaria silenciosamente os não conversores e inflaria sua taxa de conversão.
SELECT
a.user_id,
a.variant,
o.order_id
FROM assignments a
LEFT JOIN orders o
ON o.user_id = a.user_id;Contando a conversão por variante
Taxa de conversão = usuários convertidos / usuários atribuídos, por variante. Conte os conversores distintos no numerador e todos os usuários atribuídos no denominador.
Use COUNT(DISTINCT ...) no usuário do pedido para que um usuário com três pedidos ainda conte como um único convertido.
SELECT
a.variant,
COUNT(DISTINCT a.user_id) AS assigned,
COUNT(DISTINCT o.user_id) AS converters,
ROUND(100.0 * COUNT(DISTINCT o.user_id)
/ COUNT(DISTINCT a.user_id), 2) AS conv_rate_pct
FROM assignments a
LEFT JOIN orders o ON o.user_id = a.user_id
GROUP BY a.variant;A armadilha da atribuição dupla
E se um usuário aparecer duas vezes nas atribuições, uma vez em cada variante? Sua junção passará a contá-lo nos dois lados, contaminando o experimento.
Entrevistadores costumam inserir esse caso. Proteja-se contra ele: elimine as duplicatas da atribuição para manter uma única variante por usuário, normalmente a primeira atribuição, antes de fazer a junção.
WITH dedup AS (
SELECT user_id, variant,
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY assigned_at) AS rn
FROM assignments
)
SELECT user_id, variant
FROM dedup
WHERE rn = 1;Conte resultados somente após a atribuição
Um pedido feito antes da atribuição do usuário não pode ter sido causado pelo experimento. Adicione uma restrição temporal: o resultado deve ocorrer no mesmo momento ou depois de assigned_at.
Coloque essa condição na ON da cláusula LEFT JOIN para que os não conversores continuem sendo preservados.
SELECT
a.variant,
COUNT(DISTINCT a.user_id) AS assigned,
COUNT(DISTINCT o.user_id) AS converters
FROM assignments a
LEFT JOIN orders o
ON o.user_id = a.user_id
AND o.created_at >= a.assigned_at
GROUP BY a.variant;ON versus WHERE na junção de resultados
Esta é uma pergunta complementar garantida. Se você mover o.created_at >= a.assigned_at para WHERE, transformará o LEFT JOIN em uma junção interna: as linhas do usuário que nunca fez um pedido terão o.created_at = NULL, o predicado será UNKNOWN e elas desaparecerão.
Mantenha as condições de filtragem dos resultados em ON para preservar os não conversores no denominador.
Métricas de receita por variante
Além da conversão, os entrevistadores podem pedir a receita por usuário (ARPU) e a receita por conversor. Some o valor e depois divida pelo denominador correto.
O ARPU é dividido pelo total de usuários atribuídos; a receita por conversor é dividida apenas pelos usuários que fizeram pedidos. Deixe claro qual métrica a empresa deseja.
SELECT
a.variant,
COUNT(DISTINCT a.user_id) AS assigned,
COALESCE(SUM(o.amount), 0) AS revenue,
ROUND(COALESCE(SUM(o.amount), 0)
/ COUNT(DISTINCT a.user_id), 2) AS arpu
FROM assignments a
LEFT JOIN orders o
ON o.user_id = a.user_id
AND o.created_at >= a.assigned_at
GROUP BY a.variant;O padrão de agregação em dois níveis
Quando a métrica é "média de pedidos por usuário", não a calcule em uma única passagem, pois você misturaria as granularidades de usuário e de pedido. Primeiro agregue no nível do usuário e depois calcule a média entre os usuários.
Esse padrão, primeiro por usuário e depois por variante, usa a granularidade correta e é um critério comum de diferenciação em entrevistas.
WITH per_user AS (
SELECT a.variant, a.user_id,
COUNT(o.order_id) AS orders_cnt
FROM assignments a
LEFT JOIN orders o
ON o.user_id = a.user_id
AND o.created_at >= a.assigned_at
GROUP BY a.variant, a.user_id
)
SELECT variant, ROUND(AVG(orders_cnt), 3) AS avg_orders_per_user
FROM per_user
GROUP BY variant;Uma consulta completa e defensável
Combine tudo: elimine duplicatas mantendo a primeira atribuição, use a atribuição como base, aplique a restrição temporal aos resultados em ON e apresente a conversão e o ARPU por variante. Explique cada restrição à medida que a escreve.
WITH enrolled AS (
SELECT user_id, variant, assigned_at
FROM (
SELECT user_id, variant, assigned_at,
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY assigned_at) AS rn
FROM assignments
) x WHERE rn = 1
)
SELECT
e.variant,
COUNT(DISTINCT e.user_id) AS assigned,
COUNT(DISTINCT o.user_id) AS converters,
ROUND(100.0 * COUNT(DISTINCT o.user_id)
/ COUNT(DISTINCT e.user_id), 2) AS conv_pct,
ROUND(COALESCE(SUM(o.amount),0)
/ COUNT(DISTINCT e.user_id), 2) AS arpu
FROM enrolled e
LEFT JOIN orders o
ON o.user_id = e.user_id
AND o.created_at >= e.assigned_at
GROUP BY e.variant;Verificações de coerência esperadas pelos entrevistadores
Antes de apresentar os resultados, valide a configuração do experimento:
- Os tamanhos das variantes estão aproximadamente equilibrados? Uma divisão 90/10 quando se esperava 50/50 indica um erro.
- Algum usuário apareceu nas duas variantes? Conte os usuários com mais de uma variante distinta.
- Há atribuições sem uma janela possível para resultados (atribuídas depois do limite dos dados)?
Oferecer essas verificações sem ser solicitado demonstra maturidade analítica.
SELECT user_id, COUNT(DISTINCT variant) AS variant_count
FROM assignments
GROUP BY user_id
HAVING COUNT(DISTINCT variant) > 1;Verificação rápida
Você calcula a conversão por variante fazendo LEFT JOIN de pedidos com atribuições, mas coloca o.created_at >= a.assigned_at na cláusula WHERE. O que acontece?
Recapitulação: Atribuição e métricas de testes A/B
Agora você tem um roteiro defensável para analisar experimentos:
- Trate a atribuição como fonte de verdade; faça LEFT JOIN com os resultados.
- Elimine duplicatas para manter uma variante por usuário (a primeira atribuição).
- Aplique a restrição temporal aos resultados na cláusula ON, nunca em WHERE, para manter os não conversores.
- Escolha o denominador correto para conversão, ARPU e receita por conversor.
- Agregue primeiro na granularidade do usuário para obter médias por usuário.
- Faça verificações de coerência sobre o equilíbrio da divisão e atribuições cruzadas.
A seguir: transformando essas métricas por variante em incremento, significância e métricas de segurança.
Perguntas Frequentes
A aula “Atribuição e métricas de teste A/B” é grátis?
Sim — o texto completo de “Atribuição e métricas de teste A/B” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Coding Interview Prep, atualize para CoddyKit PRO. O curso de Coding Interview Prep inclui 4 aulas no total.
O que vou aprender em “Atribuição e métricas de teste A/B”?
Associando a atribuição do experimento aos resultados e calculando métricas por variante. Você pratica Coding Interview Prep com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Coding Interview Prep?
Nenhuma experiência prévia é necessária. Coding Interview Prep no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.
Quanto tempo leva a aula “Atribuição e métricas de teste A/B”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Coding Interview Prep?
Sim. Cada aula de Coding Interview Prep inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Criando um funil de várias etapas
- Eventos ordenados e janelas de tempo
- Atribuição e métricas de teste A/B
- Incremento, significância e proteções em SQL