Po pierwsze, skoro ten kod nie sypie Ci błędami od samego początku, to znaczy, że uruchamiasz go w mysql/mariadb :)
Po drugie, jeśli chcesz pisać coś dłuższego, niż jedna linijka, to zacznij to sobie formatować (wcięcia), bo inaczej nie znajdziesz błędów. A jeśli już formatujesz, to wklejając kod na forum otulaj go odpowiednim formatowaniem, żebyśmy i my to widzieli.
Po trzecie, zachęcam (inni mogą się nie zgodzić), by pisać kod w miarę uniwersalnie, bez tych mysqlowych wodotrysków - ułatwi i to analizę:
- klauzulę ON umieszczaj po złączeniu, którego dotyczy, zamiast na końcu zapytania
- w głównym zapytaniu (czyli tam, gdzie masz tego CASE'a nie używaj kolumn, których nie ma w podzapytaniu (np. C.nazwa_produktu).
Po zastosowaniu powyższych założeń otrzymałbyś taki kod:
SELECT
A.Pesel,
case
when B.Pesel IS NOT NULL AND C.Pesel IS NULL then 'zestaw2'
when C.Pesel IS NOT NULL AND B.Pesel IS NULL then 'zestaw3'
when B.Pesel IS NOT NULL AND C.Pesel IS NOT NULL then 'zestaw4'
else 'zestaw1'
end as Zestawy
FROM
(
SELECT PESEL as Pesel
FROM tabela
WHERE data_transakcji >= '2023-01-01'
AND nazwa_produktu = 'Telefon'
) as A
INNER JOIN (
SELECT PESEL as Pesel
FROM tabela
WHERE data_transakcji >= '2023-01-01'
AND nazwa_produktu = 'Ładowarka'
) as B ON A.Pesel = B.Pesel
INNER JOIN (
SELECT PESEL as Pesel
FROM tabela
WHERE data_transakcji >= '2023-01-01'
AND nazwa_produktu = 'Słuchawki'
) as C ON B.Pesel = C.Pesel
;
Teraz zauważ, że wybierasz wszystkie sprzedaże telefonów, ładowarek i słuchawek i wykonujesz iloczyn tych zbiorów (czyli na dzień dobry filtrujesz sobie jedynie tych klientów, którzy kupili wszystkie trzy przedmioty, więc CASE nie jest Ci potrzebny, bo i tak znajdziesz jedynie zestaw3
Żeby znaleźć też inne zestawy, musisz zamienić INNER JOIN na LEFT JOIN.
Swoją drogą, czy jeśli w styczniu kupię telefon, a w maju słuchawki, to chciałbyś to widzieć jako zestaw 3?
No i kolejna sprawa - jeśli kupię telefon z ładowarką i słuchawkami (zestaw 4), a do tego dokupię słuchawki, to Twoje zapytanie da Ci informację o tym, że kupiłem dwa zestawy 4. Tego oczekujesz? Jeśli nie, to musisz pomyśleć o jakimś DISTINCT gdzieś po drodze.
Jeśli masz tych zestawów kilka, to możesz sobie tak dłubać.
Ale jeśli masz kilkanaście/kilkadziesiąt/nie-daj-Boże-kilkaset produktów i z nich tworzysz znowu dziesiątki zestawów, to na pewno nie tędy droga.
Na szybko przychodzą mi do głowy dwa (pewnie głupie, ale pojawią się koledzy, którzy mnie za to zrugają) pomysły:
- Przy max 64 produktach można byłoby kodować je binarnie (telefon to 1, ładowarka 2, słuchawki 4, etui 8, itd), sumować i tym sumom przypisać zestawy (7 to zestaw 3)
- Przy większej liczbie produktów można łączyć nazwy (choć lepiej byłoby to robić na jakichś IDkach) produktów kupionych przez jednego człowieka w jeden string rozdzielając poszczególne nazwy np. średnikami i porównywać ze słownikiem.