Analityk danych
Dwa dni, dwa kanały sprzedaży, jeden raport. Zacznij od pytania kierownika i samodzielnie przejdź od tabel do wniosku.
Pobierz dane z kursu
Możesz przejść wszystkie lekcje w przeglądarce. Jeśli chcesz odtworzyć wyniki, pobierz pliki i otwórz je w odpowiednim narzędziu.
Podstawy · Lekcja 1 z 9
Od pytania do metryki
Kierownik sklepu pyta: „Jak poszła sprzedaż w ostatnich dwóch dniach?”. Ustal, jakiej liczby potrzebuje. W tym kursie sprzedaż to wartość produktów z opłaconych zamówień. Liczymy ją według daty zamówienia. Zwroty i dostawa są poza zakresem tego przykładu. Taką zdefiniowaną liczbę nazywamy metryką.
Przykład z pracy
Raport ma pokazać wartość sprzedaży za 10 i 11 listopada, osobno dla sklepu i internetu. Zamówienie anulowane nie trafia do wyniku.
Ćwiczenie praktyczne
Napisz jedno zdanie, które tłumaczy, co liczymy. Dopisz, z jakich dwóch dni bierzesz dane i które statusy wykluczasz.
Sprawdź się — opcjonalne pytanie
Czy zamówienie oczekujące na płatność wchodzi do tego raportu?
- Tak, jeśli złożono je online
- Tak, jeśli ma datę
- Nie, liczymy tylko opłacone zamówienia
Pokaż odpowiedź i wyjaśnienie
Nie, liczymy tylko opłacone zamówienia. Status płatności jest częścią definicji tej metryki. Inny raport może liczyć wszystkie złożone zamówienia.
Podstawy · Lekcja 2 z 9
Co oznacza jeden wiersz i puste pole
Zanim zaczniesz liczyć, zajrzyj do obu tabel. W „zamówieniach” jeden wiersz to jedno zamówienie. W „pozycjach” jeden wiersz to jeden rodzaj produktu w zamówieniu. Numer zamówienia może się tu powtarzać. Puste pole może oznaczać brak informacji. W SQL zapis NULL oznacza brak wartości i różni się od zera.
- Sprawdź, co oznacza wiersz
- Znajdź numer zamówienia w obu tabelach
- Wyjaśnij braki przed podsumowaniem
Przykład z pracy
Zamówienie 101 ma notesy i długopis. W pierwszej tabeli zajmuje jeden wiersz, w drugiej dwa. Gdy brakuje ceny, zapytaj, dlaczego; cena 0 zł mogłaby oznaczać darmowy produkt.
| id_zamowienia | data | kanal | status |
|---|---|---|---|
| 101 | 10 listopada | Sklep | opłacone |
| 102 | 10 listopada | Online | opłacone |
| 103 | 11 listopada | Online | opłacone |
| 104 | 11 listopada | Online | anulowane |
| 105 | 11 listopada | Sklep | opłacone |
| 106 | 11 listopada | Online | oczekuje |
| id_pozycji | id_zamowienia | produkt | ilosc | cena |
|---|---|---|---|---|
| 1 | 101 | Notes | 2 | 30 zł |
| 2 | 101 | Długopis | 1 | 20 zł |
| 3 | 102 | Kubek | 1 | 70 zł |
| 4 | 103 | Notes | 1 | 30 zł |
| 5 | 103 | Kubek | 1 | 70 zł |
| 6 | 105 | Długopis | 2 | 20 zł |
Ćwiczenie praktyczne
Znajdź zamówienie 101 w obu tabelach. Wskaż kolumnę, która je łączy, i powiedz, gdzie jej wartość może się powtarzać.
Sprawdź się — opcjonalne pytanie
Co robisz, gdy cena produktu jest pusta?
- Zamieniam ją na 0 zł
- Sprawdzam przyczynę i zgłaszam brak, zanim podam wynik
- Usuwam całe zamówienie bez sprawdzenia
Pokaż odpowiedź i wyjaśnienie
Sprawdzam przyczynę i zgłaszam brak, zanim podam wynik. Brak ceny nie mówi, że produkt był darmowy. Najpierw sprawdź źródło danych.
Podstawy · Lekcja 3 z 9
Excel: zrób tabelę przestawną
Pobierz gotowy arkusz w formacie CSV. Otwórz go przez Dane → Z tekstu/CSV i wybierz średnik jako separator. Zaznacz dane i wybierz Wstaw → Tabela przestawna. Przenieś „data” do Wierszy, „kanal” do Kolumn, „wartosc” do Wartości i ustaw Suma. To szybki sposób na podsumowanie danych bez pisania formuł dla każdej grupy.
Przykład z pracy
Każdy wiersz w arkuszu to pozycja z opłaconego zamówienia. Kolumna „wartosc” zawiera już ilość pomnożoną przez cenę. Suma dla obu dni powinna dać 290 zł.
| Data | Online | Sklep | Razem |
|---|---|---|---|
| 10 listopada | 70 zł | 80 zł | 150 zł |
| 11 listopada | 100 zł | 40 zł | 140 zł |
| Razem | 170 zł | 120 zł | 290 zł |
Ćwiczenie praktyczne
Zbuduj podsumowanie i przestaw „kanal” z Kolumn do Filtrów. Zostaw „Online” i sprawdź, które wiersze zniknęły z podsumowania lub mają niższą sumę.
Sprawdź się — opcjonalne pytanie
Excel pokazuje liczbę pozycji zamiast kwoty sprzedaży. Co sprawdzasz?
- Kolor nagłówka
- Czy daty są w kolumnach
- Czy „wartosc” to liczba i czy w polu Wartości wybrano Suma
Pokaż odpowiedź i wyjaśnienie
Czy „wartosc” to liczba i czy w polu Wartości wybrano Suma. Gdy Excel odczyta kwoty jako tekst, może wybrać zliczanie. Ustaw typ liczbowy i sumowanie.
Praca z danymi · Lekcja 4 z 9
SQL: wybierz i pogrupuj
SQL to język do zadawania pytań bazie danych. SELECT mówi, jakie kolumny chcesz zobaczyć. WHERE zostawia tylko pasujące wiersze. GROUP BY składa wiersze o tej samej dacie i kanale w jedną grupę. COUNT(*) liczy wiersze w każdej grupie, a ORDER BY ustala kolejność wyniku.
Przykład z pracy
Żeby zobaczyć liczbę opłaconych zamówień, wystarczy tabela „zamówienia”. W niej jedno zamówienie to jeden wiersz, więc COUNT(*) liczy właśnie zamówienia.
Chcesz uruchomić kod? Pobierz dane do PostgreSQL ↓. W osobnej, pustej bazie wykonaj plik startowy, a potem poniższe zapytanie. Możesz też od razu przejrzeć wynik.
SELECT data, kanal, COUNT(*) AS liczba_zamowien
FROM zamowienia
WHERE status = 'opłacone'
GROUP BY data, kanal
ORDER BY data, kanal;| data | kanal | liczba_zamowien |
|---|---|---|
| 10 listopada | Online | 1 |
| 10 listopada | Sklep | 1 |
| 11 listopada | Online | 1 |
| 11 listopada | Sklep | 1 |
Ćwiczenie praktyczne
Otwórz przykład SQL. Usuń „kanal” z SELECT, GROUP BY i ORDER BY. Opisz, jak zmienia się znaczenie jednego wiersza wyniku.
Sprawdź się — opcjonalne pytanie
Gdzie wpiszesz warunek „tylko opłacone zamówienia”?
- W WHERE
- W GROUP BY
- W ORDER BY
Pokaż odpowiedź i wyjaśnienie
W WHERE. WHERE filtruje wiersze przed grupowaniem.
Praca z danymi · Lekcja 5 z 9
SQL: połącz dwie tabele
Żeby pokazać datę i kanał przy każdym produkcie, potrzebujesz obu tabel. Użyj JOIN i wskaż po ON, że numer zamówienia ma być taki sam po obu stronach. Litery z i p to skróty nazw tabel. INNER JOIN pokazuje tylko dopasowania. LEFT JOIN zostawia też wszystkie zamówienia z lewej tabeli, nawet jeśli po prawej nie ma pozycji.
Przykład z pracy
Dla 101 zobaczysz dwa wiersze: po jednym dla notesu i długopisu. Przy LEFT JOIN zobaczysz też 104 i 106, z pustym polem produktu, bo w tym zestawie nie mają pozycji.
| id_zamowienia | data | kanal | status |
|---|---|---|---|
| 101 | 10 listopada | Sklep | opłacone |
| 102 | 10 listopada | Online | opłacone |
| 103 | 11 listopada | Online | opłacone |
| 104 | 11 listopada | Online | anulowane |
| 105 | 11 listopada | Sklep | opłacone |
| 106 | 11 listopada | Online | oczekuje |
| id_pozycji | id_zamowienia | produkt | ilosc | cena |
|---|---|---|---|---|
| 1 | 101 | Notes | 2 | 30 zł |
| 2 | 101 | Długopis | 1 | 20 zł |
| 3 | 102 | Kubek | 1 | 70 zł |
| 4 | 103 | Notes | 1 | 30 zł |
| 5 | 103 | Kubek | 1 | 70 zł |
| 6 | 105 | Długopis | 2 | 20 zł |
INNER JOIN — tylko pasujące wiersze
SELECT z.id_zamowienia, z.data, z.kanal,
p.produkt, p.ilosc, p.cena
FROM zamowienia AS z
INNER JOIN pozycje_zamowien AS p
ON z.id_zamowienia = p.id_zamowienia
ORDER BY z.id_zamowienia, p.id_pozycji;| id_zamowienia | data | kanal | produkt | ilosc | cena |
|---|---|---|---|---|---|
| 101 | 10 listopada | Sklep | Notes | 2 | 30 zł |
| 101 | 10 listopada | Sklep | Długopis | 1 | 20 zł |
| 102 | 10 listopada | Online | Kubek | 1 | 70 zł |
| 103 | 11 listopada | Online | Notes | 1 | 30 zł |
| 103 | 11 listopada | Online | Kubek | 1 | 70 zł |
| 105 | 11 listopada | Sklep | Długopis | 2 | 20 zł |
LEFT JOIN — także zamówienia bez pozycji
SELECT z.id_zamowienia, z.data, z.kanal,
p.produkt, p.ilosc, p.cena
FROM zamowienia AS z
LEFT JOIN pozycje_zamowien AS p
ON z.id_zamowienia = p.id_zamowienia
ORDER BY z.id_zamowienia, p.id_pozycji;| id_zamowienia | data | kanal | produkt | ilosc | cena |
|---|---|---|---|---|---|
| 101 | 10 listopada | Sklep | Notes | 2 | 30 zł |
| 101 | 10 listopada | Sklep | Długopis | 1 | 20 zł |
| 102 | 10 listopada | Online | Kubek | 1 | 70 zł |
| 103 | 11 listopada | Online | Notes | 1 | 30 zł |
| 103 | 11 listopada | Online | Kubek | 1 | 70 zł |
| 104 | 11 listopada | Online | NULL | NULL | NULL |
| 105 | 11 listopada | Sklep | Długopis | 2 | 20 zł |
| 106 | 11 listopada | Online | NULL | NULL | NULL |
Ćwiczenie praktyczne
Otwórz oba wyniki złączenia. Znajdź 101 oraz 104 i powiedz, skąd bierze się różnica między tymi dwoma przypadkami.
Sprawdź się — opcjonalne pytanie
Które złączenie pokaże wszystkie zamówienia, także te bez produktów w tabeli pozycji?
- INNER JOIN
- LEFT JOIN, z zamówieniami po lewej stronie
- Wystarczy ORDER BY
Pokaż odpowiedź i wyjaśnienie
LEFT JOIN, z zamówieniami po lewej stronie. LEFT JOIN zachowuje wiersze z lewej tabeli. Brakujące kolumny z prawej strony mają wartość NULL.
Praca z danymi · Lekcja 6 z 9
Sprawdź sumę po złączeniu
Po złączeniu jeden wiersz wyniku oznacza pozycję, nie całe zamówienie. Wartość pozycji to ilość razy cena. Sumujemy te wartości po odfiltrowaniu nieopłaconych zamówień. Jeśli raport ma też pokazać liczbę zamówień, użyj COUNT(DISTINCT numer_zamówienia), czyli policz każdy numer tylko raz.
Przykład z pracy
Zamówienie 101 ma dwie pozycje za 60 i 20 zł. Ich suma to 80 zł. Gdyby kwota 80 zł była zapisana przy zamówieniu i powieliła się obok obu produktów, jej prosta suma błędnie dałaby 160 zł.
SELECT z.data, z.kanal,
SUM(p.ilosc * p.cena) AS sprzedaz_zl,
COUNT(DISTINCT z.id_zamowienia) AS liczba_zamowien
FROM zamowienia AS z
INNER JOIN pozycje_zamowien AS p
ON z.id_zamowienia = p.id_zamowienia
WHERE z.status = 'opłacone'
GROUP BY z.data, z.kanal
ORDER BY z.data, z.kanal;| data | kanal | sprzedaz_zl | liczba_zamowien |
|---|---|---|---|
| 10 listopada | Online | 70 zł | 1 |
| 10 listopada | Sklep | 80 zł | 1 |
| 11 listopada | Online | 100 zł | 1 |
| 11 listopada | Sklep | 40 zł | 1 |
| Razem | Wszystkie | 290 zł | 4 |
Ćwiczenie praktyczne
Porównaj raport SQL z tabelą przestawną z lekcji 3. Gdy kwoty są różne, sprawdź najpierw statusy, potem poziom wiersza i sposób sumowania.
Sprawdź się — opcjonalne pytanie
Dlaczego COUNT(*) po złączeniu może zawyżyć liczbę zamówień?
- Bo jedno zamówienie może pojawić się przy kilku pozycjach
- Bo data jest zapisana tekstem
- Bo ORDER BY dodaje wiersze
Pokaż odpowiedź i wyjaśnienie
Bo jedno zamówienie może pojawić się przy kilku pozycjach. COUNT(*) widzi wszystkie wiersze wyniku, czyli w tym przypadku pozycje. DISTINCT pozwala policzyć każdy numer zamówienia raz.
Poziom średniozaawansowany · Lekcja 7 z 9
Power BI: zbuduj raport sprzedaży
W Power BI Desktop wczytaj obie tabele CSV i sprawdź typy kolumn: datę, numery i ceny. W widoku Model połącz obie kolumny id_zamowienia relacją 1 do wielu: jeden numer po stronie zamówień, wiele pozycji po drugiej stronie. W widoku Raport ustaw filtr strony na status „opłacone”. Dodaj kartę z miarą sprzedaży, wykres po dacie i filtr kanału.
Przykład z pracy
Miara to wzór, który liczy wynik dla aktualnie wybranych danych. Po wybraniu „Online” karta i wykres pokażą tylko sprzedaż internetową. Zobacz to na przykładzie poniżej.
Przykład do nauki inspirowany widokiem raportu Power BI. Pokazuje tylko opłacone zamówienia.
- Sprzedaż
- 290 zł
- Opłacone zamówienia
- 4
- 10 listopada
150 zł 150 zł- 11 listopada
140 zł 140 zł
- Sprzedaż
- 170 zł
- Opłacone zamówienia
- 2
- 10 listopada
70 zł 70 zł- 11 listopada
100 zł 100 zł
- Sprzedaż
- 120 zł
- Opłacone zamówienia
- 2
- 10 listopada
80 zł 80 zł- 11 listopada
40 zł 40 zł
Zbuduj ten raport w Power BI Desktop
- Wczytaj tabelę zamówień ↓ i tabelę pozycji ↓. Ustaw separator na średnik i sprawdź, czy daty i liczby mają właściwe typy.
- W widoku Model połącz
zamowienia[id_zamowienia](1) zpozycje_zamowien[id_zamowienia](wiele). Filtr powinien działać od zamówień do pozycji. - Dodaj miarę „Sprzedaż” w DAX (języku formuł Power BI). SUMX oblicza wartość każdej pozycji, a potem dodaje wyniki:
Sprzedaż =
SUMX(
pozycje_zamowien,
pozycje_zamowien[ilosc] * pozycje_zamowien[cena]
)Ustaw filtr strony na zamowienia[status] = opłacone. Wstaw kartę z miarą „Sprzedaż” i drugą z liczbą zamówień (unikatowa liczba zamowienia[id_zamowienia]). Do wykresu dodaj datę na osi i miarę „Sprzedaż” jako wartość. Dodaj fragmentator, czyli filtr widoczny na raporcie, z polem zamowienia[kanal].
Ćwiczenie praktyczne
Wybierz kolejno „Wszystkie” i „Online”. Porównaj wyniki. Jeśli budujesz raport w Power BI, ustaw na wykresie zwykłą datę zamiast automatycznej hierarchii dat, żeby zobaczyć oba dni.
Sprawdź się — opcjonalne pytanie
Po wybraniu „Online” wykres się zmienia, ale karta sprzedaży stoi w miejscu. Co sprawdzasz?
- Czy filtr ma włączony wpływ na kartę i czy miara go uwzględnia
- Czy karta jest nad wykresem
- Czy zmienił się kolor słupka
Pokaż odpowiedź i wyjaśnienie
Czy filtr ma włączony wpływ na kartę i czy miara go uwzględnia. W Power BI da się wyłączyć wpływ filtra na wybraną wizualizację, a niektóre miary mogą świadomie pomijać filtr.
Poziom średniozaawansowany · Lekcja 8 z 9
Funkcje okna w SQL
Sklep zapisuje każdą zmianę statusu w osobnym wierszu. Żeby znaleźć aktualny status, nadaj wierszom numery w obrębie każdego zamówienia. ROW_NUMBER z PARTITION BY zaczyna liczenie od nowa dla kolejnego numeru zamówienia. ORDER BY ustawia najnowszy wpis jako pierwszy. Jeśli dwa wpisy mają tę samą godzinę, drugi warunek sortowania rozstrzyga remis.
Przykład z pracy
Zamówienie 101 było najpierw w statusie „oczekuje”, a potem „opłacone”. W wyniku zostaje „opłacone”. W przeciwieństwie do GROUP BY funkcja okna sama nie skleja wierszy; wybieramy wiersz numer 1 w zewnętrznym zapytaniu.
To zapytanie zawiera własną krótką historię statusów. Możesz je uruchomić bez wczytywania pliku startowego.
WITH historia(id_wpisu, id_zamowienia, czas, status) AS (
VALUES
(1, 101, '2026-11-10 09:00', 'oczekuje'),
(2, 101, '2026-11-10 09:05', 'opłacone'),
(3, 104, '2026-11-11 10:00', 'oczekuje'),
(4, 104, '2026-11-11 10:00', 'anulowane')
), ponumerowane AS (
SELECT id_zamowienia, status,
ROW_NUMBER() OVER (
PARTITION BY id_zamowienia
ORDER BY czas DESC, id_wpisu DESC
) AS nr
FROM historia
)
SELECT id_zamowienia, status
FROM ponumerowane
WHERE nr = 1
ORDER BY id_zamowienia;| id_zamowienia | status |
|---|---|
| 101 | opłacone |
| 104 | anulowane |
Ćwiczenie praktyczne
Przejrzyj historię w zapytaniu. Wskaż aktualny status 104. Zmień kolejność na rosnącą dla czasu i numeru wpisu i wyjaśnij, co teraz pokazuje wynik.
Sprawdź się — opcjonalne pytanie
Dwa wpisy mają tę samą datę i godzinę. Jak wybrać ostatni?
- Zostawiam oba wpisy jako aktualne
- Sortuję dodatkowo po polu, które rozstrzyga kolejność wpisów
- Wybieram status alfabetycznie
Pokaż odpowiedź i wyjaśnienie
Sortuję dodatkowo po polu, które rozstrzyga kolejność wpisów. W przykładzie większy numer wpisu oznacza późniejszy zapis. W pracy potwierdź tę regułę w dokumentacji systemu.
Poziom średniozaawansowany · Lekcja 9 z 9
Wyjaśnij wynik i zaproponuj sprawdzenie
Zacznij od tego, co widać, i dodaj, czego jeszcze nie wiemy. Porównaj sprzedaż ogółem i osobno w każdym kanale. Dwa dni wystarczą do opisania tej zmiany, ale to za mało, żeby nazwać ją trendem albo przypisać ją promocji.
Przykład z pracy
Sprzedaż ogółem spadła z 150 do 140 zł. Online wzrósł z 70 do 100 zł, a sklep stacjonarny spadł z 80 do 40 zł. Sprawdzę, czy różnica powtarza się w porównywalnych dniach i czy zmienił się ruch lub dostępność produktów.
Ćwiczenie praktyczne
Przygotuj trzyzdaniową notatkę dla kierownika: wynik ogółem, różnica między kanałami i jedno konkretne pytanie do dalszej analizy. Dołącz wykres z lekcji 7.
Symulacja rozmowy
Dlaczego po połączeniu tabel przychód mógł wzrosnąć?
Porównaj z przykładową odpowiedzią
Jeśli zamówienie za 100 zł ma trzy produkty, po połączeniu tabel kwota 100 zł może pojawić się trzy razy. Sprawdzę, ile wierszy przypada na zamówienie i zsumuję jego kwotę tylko raz.
Sprawdź się — opcjonalne pytanie
Po dwóch dniach widzisz wzrost online. Co możesz powiedzieć kierownikowi?
- Promocja na pewno zadziałała
- Wzrost będzie się powtarzał
- Sprzedaż online wzrosła w tych dniach; przyczynę trzeba sprawdzić
Pokaż odpowiedź i wyjaśnienie
Sprzedaż online wzrosła w tych dniach; przyczynę trzeba sprawdzić. Dane pokazują, co się zmieniło. Żeby wyjaśnić dlaczego, potrzebujesz np. informacji o promocji, ruchu lub zapasach.