0Pricing
SQL Interview Prep · Lekcja

Przypisywanie do testu A/B i metryki

Łączenie przypisania do eksperymentu z wynikami oraz obliczanie metryk dla poszczególnych wariantów.

Przypisywanie do testu A/B i metryki to bezpłatna lekcja SQL Interview Prep na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej SQL Interview Prep, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs SQL Interview Prep zawiera 4 lekcji w sumie.

Co sprawdza pytanie o test A/B

Pytania o testy A/B sprawdzają, czy potrafi Pan/Pani poprawnie połączyć przypisanie do eksperymentu z wynikami i obliczyć przejrzystą metrykę dla każdego wariantu.

Pułapka niemal zawsze tkwi w złączeniu: można policzyć wyniki użytkowników, którzy nigdy nie zostali objęci eksperymentem, albo podwójnie policzyć użytkowników przypisanych dwukrotnie. Jeśli złączenie z tabelą przypisań jest poprawne, obliczenie metryk jest już prostą arytmetyką.

Dwie otrzymywane tabele

Należy spodziewać się tabeli przypisań oraz tabeli wyników:

  • assignments(user_id, variant, assigned_at), w której wariant to 'control' lub 'treatment'.
  • orders(user_id, order_id, amount, created_at) albo ogólnej tabeli zdarzeń.

Tabela przypisań jest źródłem prawdy określającym, którzy użytkownicy biorą udział w eksperymencie. Wyniki należy uwzględniać tylko wtedy, gdy użytkownik występuje w tabeli przypisań.

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
);

Rozpoczynanie od przypisań i użycie LEFT JOIN do wyników

Podstawowa zasada: punktem wyjścia powinna być tabela przypisań, do której należy wykonać LEFT JOIN wyników. Dzięki temu zachowani zostaną użytkownicy objęci eksperymentem, którzy nigdy nie dokonali konwersji — są oni potrzebni do prawidłowego wyznaczenia mianownika.

INNER JOIN po cichu odrzuciłby użytkowników bez konwersji i zawyżył współczynnik konwersji.

SELECT
  a.user_id,
  a.variant,
  o.order_id
FROM assignments a
LEFT JOIN orders o
  ON o.user_id = a.user_id;

Liczenie konwersji dla każdego wariantu

Współczynnik konwersji = liczba użytkowników, którzy dokonali konwersji / liczba przypisanych użytkowników, osobno dla każdego wariantu. W liczniku należy policzyć unikalnych użytkowników dokonujących konwersji, a w mianowniku wszystkich przypisanych użytkowników.

Należy użyć COUNT(DISTINCT ...) dla użytkownika zamówienia, aby użytkownik z trzema zamówieniami nadal był liczony jako jeden użytkownik dokonujący konwersji.

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;

Pułapka podwójnego przypisania

Co się stanie, jeśli użytkownik pojawi się w tabeli przypisań dwukrotnie, raz w każdym wariancie? Złączenie policzy go po obu stronach, a eksperyment zostanie zanieczyszczony.

Rekrutujący często celowo sprawdzają ten przypadek. Należy się przed nim zabezpieczyć: przed złączeniem trzeba usunąć duplikaty przypisań, pozostawiając jeden wariant na użytkownika — zazwyczaj przypisanie pierwsze.

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;

Uwzględnianie tylko wyników po przypisaniu

Zamówienie złożone przed przypisaniem użytkownika nie mogło być spowodowane eksperymentem. Należy dodać ograniczenie czasowe: wynik musi wystąpić w chwili przypisania lub później, czyli o czasie większym lub równym assigned_at.

Ten warunek należy umieścić w klauzuli ON złączenia LEFT JOIN, aby zachować użytkowników bez konwersji.

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 a WHERE w złączeniu wyników

To gwarantowane pytanie uzupełniające. Jeśli o.created_at >= a.assigned_at zostanie przeniesione do WHERE, LEFT JOIN zmieni się w złączenie wewnętrzne: wiersze użytkowników, którzy nigdy nie złożyli zamówienia, mają wartość o.created_at = NULL, predykat ma wartość UNKNOWN, a wiersze te znikają.

Warunki filtrowania wyników należy pozostawić w ON, aby zachować użytkowników bez konwersji w mianowniku.

Metryki przychodu dla poszczególnych wariantów

Poza konwersją rekrutujący pytają o przychód na użytkownika (ARPU) oraz przychód na użytkownika dokonującego konwersji. Należy zsumować kwoty, a następnie podzielić je przez właściwy mianownik.

ARPU dzieli się przez wszystkich przypisanych użytkowników, natomiast przychód na użytkownika dokonującego konwersji — tylko przez użytkowników, którzy złożyli zamówienie. Należy jasno określić, której wartości potrzebuje firma.

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;

Wzorzec agregacji dwupoziomowej

Jeśli metryka oznacza "średnią liczbę zamówień na użytkownika", nie należy obliczać jej w jednym przebiegu, ponieważ połączone zostałyby poziomy użytkownika i zamówienia. Najpierw należy dokonać agregacji na poziomie użytkownika, a dopiero potem obliczyć średnią dla wszystkich użytkowników.

Wzorzec „najpierw na użytkownika, potem na wariant” zapewnia prawidłowy poziom agregacji i często pozwala odróżnić lepsze odpowiedzi podczas rozmowy.

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;

Kompletne, uzasadnione zapytanie

Należy połączyć wszystkie elementy: usunąć duplikaty, pozostawiając pierwsze przypisanie, rozpocząć od tabeli przypisań, ograniczyć czas wyników w ON i zwrócić konwersję oraz ARPU dla każdego wariantu. Podczas pisania zapytania należy wyjaśniać rolę każdego ograniczenia.

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;

Kontrole poprawności oczekiwane przez rekrutujących

Przed przedstawieniem wyników należy zweryfikować konfigurację eksperymentu:

  • Czy liczebności wariantów są w przybliżeniu zrównoważone? Podział 90/10, gdy planowano 50/50, wskazuje na błąd.
  • Czy któryś użytkownik trafił do obu wariantów? Należy policzyć użytkowników przypisanych do więcej niż jednego unikalnego wariantu.
  • Czy istnieją przypisania bez możliwego okna wyników, ponieważ przypisanie nastąpiło po punkcie odcięcia danych?

Samodzielne zaproponowanie takich kontroli świadczy o dojrzałości analitycznej.

SELECT user_id, COUNT(DISTINCT variant) AS variant_count
FROM assignments
GROUP BY user_id
HAVING COUNT(DISTINCT variant) > 1;

Szybkie sprawdzenie

Współczynnik konwersji dla każdego wariantu jest obliczany przez wykonanie LEFT JOIN zamówień z przypisaniami, ale warunek o.created_at >= a.assigned_at umieszczono w klauzuli WHERE. Co się stanie?

Podsumowanie: przypisania i metryki w teście A/B

Ma Pan/Pani teraz zestaw zasad uzasadnionej analizy eksperymentów:

  • Należy traktować przypisanie jako źródło prawdy i wykonywać LEFT JOIN wyników.
  • Należy usunąć duplikaty, pozostawiając jeden wariant na użytkownika (pierwsze przypisanie).
  • Wyniki należy ograniczać czasowo w klauzuli ON, nigdy w WHERE, aby zachować użytkowników bez konwersji.
  • Należy wybrać właściwy mianownik dla konwersji, ARPU i przychodu na użytkownika dokonującego konwersji.
  • W przypadku średnich obliczanych na użytkownika należy najpierw przeprowadzić agregację na poziomie użytkownika.
  • Należy przeprowadzać kontrole poprawności równowagi podziału oraz przypisań do wielu wariantów.

Dalej: przekształcanie tych metryk dla poszczególnych wariantów w lift, istotność i metryki ochronne.

Często zadawane pytania

Czy lekcja „Przypisywanie do testu A/B i metryki” jest bezpłatna?

Tak — pełny tekst „Przypisywanie do testu A/B i metryki” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu SQL Interview Prep, przejdź na CoddyKit PRO. Kurs SQL Interview Prep zawiera 4 lekcji w sumie.

Co nauczysz się w „Przypisywanie do testu A/B i metryki”?

Łączenie przypisania do eksperymentu z wynikami oraz obliczanie metryk dla poszczególnych wariantów. Ćwiczysz SQL Interview Prep z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć SQL Interview Prep?

Nie wymagamy żadnego doświadczenia. SQL Interview Prep w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.

Ile czasu zajmuje lekcja „Przypisywanie do testu A/B i metryki”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji SQL Interview Prep?

Tak. Każda lekcja SQL Interview Prep zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Budowanie wieloetapowego lejka
  2. Uporządkowane zdarzenia i okna czasowe
  3. Przypisywanie do testu A/B i metryki
  4. Wzrost, istotność i zabezpieczenia w SQL
← Powrót do SQL Interview Prep