Assegnazione e metriche dei test A/B
Unione dell'assegnazione all'esperimento con i risultati e calcolo delle metriche per variante.
Assegnazione e metriche dei test A/B è una lezione Coding Interview Prep gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Coding Interview Prep, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Coding Interview Prep include 4 lezioni in totale.
Che cosa verifica una domanda su un test A/B
Le domande sui test A/B verificano se sa collegare correttamente l'assegnazione dell'esperimento agli esiti e calcolare una metrica chiara per variante.
La trappola si trova quasi sempre nel join: contare gli esiti di utenti che non sono mai stati inclusi nell'esperimento oppure contare due volte utenti assegnati due volte. Se il join con l'assegnazione è corretto, le metriche sono semplici calcoli aritmetici.
Le due tabelle disponibili
Si aspetti una tabella delle assegnazioni e una tabella degli esiti:
assignments(user_id, variant, assigned_at), dove la variante è 'control' o 'treatment'.orders(user_id, order_id, amount, created_at)oppure una tabella generica degli eventi.
L'assegnazione è la fonte autorevole per stabilire chi partecipa all'esperimento. Gli esiti contano solo se l'utente compare nella tabella delle assegnazioni.
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
);Partire dalle assegnazioni ed eseguire un LEFT JOIN con gli esiti
La regola fondamentale è partire dalla tabella delle assegnazioni ed eseguire un LEFT JOIN con gli esiti. In questo modo si mantengono gli utenti inclusi nell'esperimento che non hanno mai convertito, necessari per avere un denominatore corretto.
Un INNER JOIN eliminerebbe silenziosamente i non convertiti e gonfierebbe il tasso di conversione.
SELECT
a.user_id,
a.variant,
o.order_id
FROM assignments a
LEFT JOIN orders o
ON o.user_id = a.user_id;Contare le conversioni per variante
Il tasso di conversione è uguale a utenti convertiti / utenti assegnati, per variante. Conti gli utenti convertiti distinti al numeratore e tutti gli utenti assegnati al denominatore.
Utilizzi COUNT(DISTINCT ...) sull'utente dell'ordine, così un utente con tre ordini conta comunque come un solo utente convertito.
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;La trappola della doppia assegnazione
Che cosa accade se un utente compare due volte nella tabella delle assegnazioni, una volta per ciascuna variante? Il join lo conterà su entrambi i lati e l'esperimento sarà contaminato.
È un caso inserito intenzionalmente dagli intervistatori. Si protegga da questo problema: deduplichi le assegnazioni in modo da mantenere una sola variante per utente, in genere la prima assegnazione, prima di eseguire il join.
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;Contare solo gli esiti successivi all'assegnazione
Un ordine effettuato prima dell'assegnazione dell'utente non può essere stato causato dall'esperimento. Aggiunga un vincolo temporale: l'esito deve verificarsi nello stesso momento o dopo assigned_at.
Inserisca questa condizione nella clausola ON del LEFT JOIN, così i non convertiti continueranno a essere mantenuti.
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 e WHERE nel join con gli esiti
Questa è una domanda di approfondimento praticamente garantita. Se sposta o.created_at >= a.assigned_at in WHERE, trasforma il LEFT JOIN in un inner join: nelle righe in cui l'utente non ha mai effettuato ordini, o.created_at = NULL, il predicato è UNKNOWN e tali righe scompaiono.
Mantenga le condizioni di filtro sugli esiti in ON per preservare i non convertiti nel denominatore.
Metriche dei ricavi per variante
Oltre alla conversione, gli intervistatori possono chiedere i ricavi per utente (ARPU) e i ricavi per utente convertito. Sommi l'importo, quindi lo divida per il denominatore corretto.
L'ARPU si calcola dividendo per tutti gli utenti assegnati; i ricavi per utente convertito si calcolano dividendo solo per gli utenti che hanno effettuato un ordine. Specifichi chiaramente quale metrica richiede l'azienda.
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;Il modello di aggregazione a due livelli
Quando una metrica è la «media di ordini per utente», non la calcoli in un unico passaggio: finirebbe per mescolare la granularità dell'utente con quella dell'ordine. Esegua prima l'aggregazione al livello dell'utente, quindi calcoli la media tra gli utenti.
Questo modello, prima per utente e poi per variante, usa la granularità corretta ed è un criterio discriminante comune nei colloqui.
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;Una query completa e difendibile
Combini tutti gli elementi: deduplichi mantenendo la prima assegnazione, parta dalla tabella delle assegnazioni, applichi il vincolo temporale agli esiti in ON e riporti la conversione e l'ARPU per variante. Descriva ogni vincolo mentre lo scrive.
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;Controlli di coerenza attesi dagli intervistatori
Prima di comunicare i risultati, convalidi la configurazione dell'esperimento:
- Le dimensioni delle varianti sono approssimativamente bilanciate? Una suddivisione 90/10 quando era previsto 50/50 indica un bug.
- Qualche utente è finito in entrambe le varianti? Conti gli utenti con più di una variante distinta.
- Esistono assegnazioni senza una possibile finestra per gli esiti, perché l'assegnazione è successiva al limite temporale dei dati?
Proporre spontaneamente questi controlli dimostra maturità analitica.
SELECT user_id, COUNT(DISTINCT variant) AS variant_count
FROM assignments
GROUP BY user_id
HAVING COUNT(DISTINCT variant) > 1;Verifica rapida
Calcola la conversione per variante eseguendo un LEFT JOIN degli ordini alle assegnazioni, ma inserisce o.created_at >= a.assigned_at nella clausola WHERE. Che cosa accade?
Riepilogo: assegnazione e metriche nei test A/B
Ora dispone di un metodo difendibile per analizzare gli esperimenti:
- Consideri l'assegnazione come fonte autorevole ed esegua un LEFT JOIN con gli esiti.
- Deduplichi mantenendo una sola variante per utente (la prima assegnazione).
- Applichi il vincolo temporale agli esiti nella clausola ON, mai in WHERE, per mantenere i non convertiti.
- Scelga il denominatore corretto per la conversione, l'ARPU e i ricavi per utente convertito.
- Aggrèghi prima alla granularità dell'utente per calcolare le medie per utente.
- Esegua controlli di coerenza sull'equilibrio della suddivisione e sulle assegnazioni multiple.
Successivo: trasformare queste metriche per variante in lift, significatività e metriche guardrail.
Domande Frequenti
La lezione «Assegnazione e metriche dei test A/B» è gratuita?
Sì — il testo completo di «Assegnazione e metriche dei test A/B» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Coding Interview Prep, passa a CoddyKit PRO. Il corso Coding Interview Prep include 4 lezioni in totale.
Cosa imparerò in «Assegnazione e metriche dei test A/B»?
Unione dell'assegnazione all'esperimento con i risultati e calcolo delle metriche per variante. Eserciti Coding Interview Prep con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Coding Interview Prep?
Non è richiesta alcuna esperienza precedente. Coding Interview Prep su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.
Quanto tempo richiede la lezione «Assegnazione e metriche dei test A/B»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Coding Interview Prep?
Sì. Ogni lezione Coding Interview Prep include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Creare un funnel a più passaggi
- Eventi ordinati e finestre temporali
- Assegnazione e metriche dei test A/B
- Incremento, significatività e controlli di sicurezza in SQL