ok to tak
- bierzesz WSZYSTKICH kontrahentów
Kopiuj
select klient_id from klienci
- do tego WSZYSTKIE grupy towarów
Kopiuj
select grupa from towary group by grupa
indeks na polu grupa wysoce zalecany
3. do tego dokładasz sprzedaż na grupy
Kopiuj
select s.klient,t.grupa, sum(s.wartosc) wartosc
from sprzedaz s, towary t where t.id = s.t_id
group by s.klient,t.grupa
- łączysz to wszystko do "kupy"
Kopiuj
select
x.klient,
x.grupa,
s. wartosc
from
(select k.klient, t.grupa from klienci k, towary t group by k.klient, t.grupa) x,
(select s.klient, t.grupa, sum(s.wartosc) wartosc from sprzedaz s, towary t where t.id = s.t_id group by s.klient,t.grupa) s
where
s.klient(+) = x.klient
and s.grupa(+) = x.klient
i masz to co chciałeś
group by s.klient,t.grupa
baza testowa
kontrahentów 7310 rekordów
grup towarowych 16 rekordów
kartezjan 116960 rekordów
faktur 53917 rekordów
pozycji faktur 519255 rekordów
sprzedaż z podziałem na kontrahentów i grupy 2051 rekordów (wiem, że mało ale taką mam bazę)
zapytania na danych jakie mam
Kopiuj
SELECT
x.id_k,
x.grupa,
s.wartosc
FROM
(SELECT k.id_k, t.grupa FROM kokontr k, (SELECT t.grupa FROM totowar t GROUP BY t.grupa) t) x,
(select f.id_k, t.grupa, sum(p.wa_net) wartosc from fa_dok_nag f, fa_dok_poz p, totowar t where p.id_dok_nag = f.id AND p.towar = t.towar GROUP BY f.id_k, t.grupa) s
WHERE
s.id_k(+) = x.id_k
AND s.grupa(+) = x.grupa
i plan

i czas wykonania pomiędzy .466 a .531 sekundy
oraz z union i cross join
Kopiuj
FROM (SELECT
f.id_k,
t.grupa,
SUM(f.wa_net) wartosc
FROM
fa_dok_nag f
JOIN fa_dok_poz p ON p.id_dok_nag = f.id
JOIN totowar t ON t.towar = p.towar
GROUP BY
f.id_k,
t.grupa
UNION ALL
SELECT
k.id_k,
t.grupa,
0 wartosc
FROM
kokontr k
CROSS JOIN (SELECT DISTINCT i.grupa FROM totowar i) t
plan

czas wykonania pomiędzy 0.459 A 0.537 sekundy
Są to czasy samego wykonania bez pobierania danych bo do bazy jestem podpięty zdalnie i leciałoby to dość długo.
Moim celem nie jest pokazanie wyższości jednego nad drugim tylko pokazać, że czasami kombinowanie nie ma sensu i lepiej napisać coś najprościej jak można bo i tak na jedno wyjdzie
EDIT:
na górze się machnąłem - zamiast
Kopiuj
(select k.klient, t.grupa from klienci k, towary t group by k.klient, t.grupa) x,
musi być
Kopiuj
(SELECT k.id_k, t.grupa FROM kokontr k, (SELECT t.grupa FROM totowar t GROUP BY t.grupa) t) x,
ponieważ pierwsze wydłuża czas zapytania do prawie 6 sekund, czyli 10 razy dłużej!
BTW zamiana grupowania na distinct nic nie zmienia
EDIT2:
teraz zauważyłem, że drugi kod ma niepotrzebną agregację