Mapa tygodnia/Moduł 06
analiza-danych
sql
bigquery
40 min · średni

Case: Marketing Manager — od pytania do raportu na żywych danych

Realny przypadek sklepu internetowego: 3 źródła danych, 4 pułapki techniczne, jedna metryka (ERS) i raport, który spina to wszystko w 5 minut zamiast 5 godzin.

Tryb: pełny

Executive summary

  • Sklep Shoper + Google Ads + Facebook Ads + afiliacja + GA4 — typowy stack małego e-commerce. Pytanie szefa: „ile wydaliśmy, ile zarobiliśmy, jaki ERS per kanał?". Brzmi prosto. Nie jest.
  • 4 techniczne pułapki: (1) status płatności jest TYLKO w sklepie, nie w GA4. (2) kanał marketingowy jest TYLKO w GA4, nie w sklepie. (3) GA4 traci ~10% transakcji przez adblocki/błędy implementacji. (4) koszty są w innym poziomie agregacji niż transakcje (dzień+kanał vs zamówienie).
  • Sekwencja: pobierz dane sklepu (lista wszystkich opłaconych transakcji = źródło prawdy) → dołącz kanał z GA4 po order_id (LEFT JOIN, brakujące = „adblock") → osobno zsumuj koszty per dzień+kanał → POŁĄCZ z transakcjami zagregowanymi do dnia+kanału (NIE per zamówienie, bo zduplikujesz koszty!).
  • ERS = koszty/przychody × 100%. Im niższy, tym lepiej. Sklep z ERS > założonego progu (np. 15%) musi zoptymalizować ten kanał. Ten case study to most między „rozumiem SQL" (lekcja 5) a „wiem, dlaczego potrzebuję hurtowni" (lekcja 7).

Czym to jest

Pełny end-to-end case marketing managera, który ma za zadanie zbudować jeden codzienny raport efektywności marketingu dla zarządu. Pokazuje, dlaczego „wystarczy pobrać dane do Excela" jest piękną teorią, która rozbija się o cztery realne problemy techniczne — i jak ten sam problem rozwiązuje się raz, w BigQuery + SQL, dla każdej kolejnej skali.

Kluczowe pojęcia

ERS — Effective Revenue Share
Udział kosztów reklamowych w wygenerowanych przychodach. ERS = (koszty / przychody opłacone) × 100%. Im niższy, tym lepiej. Odwrotność ROAS.
Źródło prawdy
Główne źródło dla raportu (tu: panel sklepu — bo zawiera WSZYSTKIE transakcje, w tym te zablokowane przez adblock w GA4).
LEFT JOIN
Łączenie tabel, w którym zachowujesz wszystkie wiersze z LEWEJ tabeli (sklep) i dokładasz dopasowane z prawej (GA4). Brakujące dopasowania = NULL (tu: oznaczone jako kanał „adblock").
Poziom agregacji
Każda tabela ma własną granulację. Transakcje = per zamówienie. Koszty = per dzień+kanał. Żeby je sensownie połączyć, MUSISZ najpierw zagregować transakcje do tego samego poziomu (dzień+kanał).
Multiplikacja danych
Klasyczny błąd: dołączasz koszt dzienny do każdej transakcji tego dnia — i koszt liczy się N razy. Wynik: ERS 5x większy niż realny. Stąd grupowanie ZANIM łączenie.
Adblock / utrata danych
~5–15% transakcji w typowym e-commerce jest „niewidocznych" dla GA4 (wtyczki, JS off, błąd implementacji). Sklep widzi je w bazie zamówień — to dlatego sklep jest źródłem prawdy.
Atrybucja kanałowa
Przypisanie sprzedaży do źródła ruchu (organic, paid, social, affiliate). W GA4 zwykle „last non-direct click". Każdy model atrybucji da inny ERS.

Pryncypia

  1. 01ZAWSZE wskaż jedno źródło prawdy. Dla transakcji w e-commerce to panel sklepu, nie GA4.
  2. 02Najpierw agreguj transakcje do tego samego poziomu co koszty (dzień+kanał), DOPIERO POTEM łącz. Inaczej dostajesz multiplikację.
  3. 03Brakujące wiersze po LEFT JOIN to NIE BŁĄD — to informacja. Oznacz je jako osobny kanał („adblock") i policz, ile tracisz w atrybucji.
  4. 04Najgorsza pochwała szefa to „świetny raport — chcę go codziennie o 11:00". W tym momencie wiesz, że potrzebujesz hurtowni (lekcja 7), nie Excela.
  5. 05ERS sam w sobie nic nie znaczy — sensowny jest tylko porównawczo (między kanałami, w czasie, vs cel ustalony dla branży).

Przykłady zastosowań

Mismatch danych sklep vs GA4

Sklep widzi 5 zamówień na 4750 zł (status: 4 opłacone, 1 oczekujące). GA4 widzi tylko 4 zamówienia — brakuje #2, które nie jest „oczekujące", tylko zostało zablokowane przez wtyczkę adblock u klienta. Realny przychód: 4000 zł (tylko opłacone). Z GA4 wyciągasz źródło ruchu dla 3 z 4 (#5 też zablokowane). Reszta = kanał „adblock".

Pułapka multiplikacji

Tabela transakcji: 10 zamówień Google Ads w jednym dniu po 200 zł. Tabela kosztów: 1 wiersz Google Ads = 300 zł kosztu tego dnia. Naiwne JOIN „każda transakcja dostaje koszt 300 zł" → łączny koszt liczy się 10 razy = 3000 zł zamiast 300. ERS pokazuje 150% zamiast 15%. Klasyk.

Poprawne grupowanie

Najpierw GROUP BY day, channel na transakcjach → 1 wiersz: „Google Ads, 2026-01-15, revenue_paid=2000 zł". Osobno GROUP BY day, channel na kosztach → 1 wiersz: „Google Ads, 2026-01-15, cost=300 zł". LEFT JOIN USING (day, channel) → ERS = 300/2000 = 15%. Prawda.

Case study

Sklep dziecięcy: od 6h/tydz. w Excelu do dashboardu codziennie o 9:00

Sklep X (akcesoria niemowlęce, online-only, platforma Shoper). Marketing: Google Ads, Facebook Ads, afiliacja (Ceneo). Tracking: GA4. Wymagania zarządu: codzienny raport ERS per kanał, zawsze aktualny, w jednym widoku.

Podejście

  1. 1.Faza 1 (tydzień 1): manager robi raport ręcznie. Loguje się do 4 paneli, eksportuje 4 CSV, w Excelu robi VLOOKUP po order_id (transakcje sklep ↔ kanał GA4), oznacza brakujące jako „adblock", grupuje przez tabelę przestawną dzień+kanał, dokleja koszty z 3 systemów reklamowych, oblicza ERS. Czas: 6h. Szef: „świetne, codziennie o 11:00".
  2. 2.Faza 2 (tydzień 2): manager pisze ten sam workflow jako 3 zapytania SQL w BigQuery — sales_by_day_channel, costs_by_day_channel, final = LEFT JOIN. Gemini pomaga z syntax. Dane są wciąż ładowane ręcznie codziennie (eksport → upload → tabela).
  3. 3.Faza 3 (tydzień 3+): manager wdraża konektor Make + BigQuery Data Transfer Service do automatycznego dziennego pobierania. Raport w Looker Studio odświeża się o 8:00. Manager dostaje slacka, że raport gotowy, o 9:00 wysyła zarządowi linka.
  4. 4.Faza 4 (miesiąc 2): manager rozmawia z kolegą z większej firmy (7 rynków) i rozumie, że właśnie zbudował własną mini-hurtownię. Lekcja 7 (Hurtownia) staje się następnym krokiem — bo już teraz, przy 1 rynku, każde nowe źródło (np. TikTok Ads) to godzina pracy.
Efekt: Z 6h/tyg. → 5 min (sprawdzenie alertu, jeśli ERS w którymś kanale > 20%). Bonus: manager znajduje, że afiliacja ma ERS 20% (cel: max 15%) i optymalizuje stawki — oszczędność 4 000 zł/miesiąc bez utraty przychodu.

Najczęstsze błędy — checklista

0/5 oznaczone

Prompty gotowe do użycia

Replikacja case'u dla mojego sklepu

Kiedy: Masz własny e-commerce i chcesz wygenerować szkic SQL dla raportu ERS.

Jesteś analitykiem BI specjalizującym się w e-commerce. Mam sklep [PLATFORMA] z następującymi źródłami danych w BigQuery:

1) Tabela orders (z panelu sklepu) — kolumny: [WYPISZ Z TYPAMI]. Status płatności jest tutaj.
2) Tabela ga4_transactions — kolumny: [WYPISZ]. Tu jest channel (source/medium), ale brakuje ~10% transakcji przez adblocki.
3) Tabele kosztów per kanał: ads_google, ads_meta, ads_affiliate — wszystkie z kolumnami (date, cost). Inne agregacje.

Napisz zapytanie BigQuery zwracające: dzień, kanał, revenue_paid (tylko opłacone), cost, ers (%). Wymagania:
a) Źródłem prawdy o transakcjach JEST orders, nie ga4.
b) Channel pobierz LEFT JOIN po order_id z ga4_transactions, brakujące oznacz jako „adblock".
c) Koszty z 3 tabel połącz przez UNION ALL, ujednolicony channel name.
d) Najpierw zagreguj transakcje do dnia+kanału, DOPIERO POTEM LEFT JOIN z kosztami (uniknięcie multiplikacji).
e) Filtr ostatnie 30 dni. SAFE_DIVIDE dla ERS. ORDER BY day DESC, ers DESC.

Po zapytaniu napisz 3 testy weryfikacyjne (np. „suma revenue_paid w wyniku = suma revenue z orders WHERE status='paid' w tym samym okresie").

Częsty błąd: Najczęstszy błąd implementacyjny w prompcie: zapomnieć powiedzieć, że orders jest źródłem prawdy. Wtedy AI robi raport z GA4 i tracisz 10% revenue w raporcie.

LAB — ćwiczenie

LAB · 25 min · średni

Zaprojektuj minimum wiable raport ERS dla wymyślonego sklepu — bez pisania SQL, w pseudokodzie / diagramie kroków.

  1. 1Zaprojektuj end-to-end raport ERS dla wymyślonego sklepu.

Pytania kontrolne

Powiązane moduły

Skończyłeś moduł? Oznacz go i ruszaj dalej.