Bardzo podobne do istniejących odpowiedzi, ale to:
select months.month, mv.mycost, coalesce(mv.mynumber, 0) as mynumber
from (
select to_char(date '1970-01-01'
+ numtoyminterval(level - 1, 'month'), 'mm') as month
from dual
connect by level <= 12) months
left join myoracle_mv mv
on mv.month = months.month
order by months.month, mv.mycost, mv.mynumber;
daje to wraz z opublikowanymi danymi:
MONTH MYCOST MYNUMBER
----- ------ ----------
01 AAA 3777.24
01 BBB 18811
01 CCC 3845.47
02 AAA 49973.12
02 BBB 29872.67
02 CCC 3050.54
03 AAA 4049.91
03 BBB 29068.55
03 CCC 3784.44
03 DDD 107.07
04 AAA 469.485
04 BBB 264957.8
04 CCC 799.73
04 DDD 181.78
05 AAA 5872.22
05 BBB 67673
05 CCC 124884.2
05 DDD 110.09
06 AAA 65837.71
06 BBB 855.02
06 CCC 5157.24
06 DDD 18016.19
07 AAA 566.23
07 BBB 5226.1
07 CCC 19184.78
07 DDD 1772.95
08 AAA 18432.95
08 BBB 2663.24
08 CCC 2280.05
08 DDD 63.32
09 0
10 0
11 0
12 AAA 4337.75
12 BBB 5490.58
35 rows selected
Jeśli chcesz, aby zero pojawiło się w mynumber
kolumna, możesz to zrobić:
select months.month, mv.mycost, coalesce(mv.mynumber, 0) as mynumber
co daje:
...
08 DDD 63.32
09 0
10 0
11 0
12 AAA 4337.75
...
Z komentarzy do odpowiedzi Jafara wydaje się, że być może sam zaszedłeś tak daleko, ale chcesz zerowych wartości dla wszystkich mycost
wartości dla wszystkich miesięcy. Jeśli tak jest, musisz uzyskać listę możliwych wartości dla mycost
i zewnętrzne dołączenie do tego. Pobiera to wszystkie wartości, które są już w MV:
select months.month, costs.mycost, coalesce(mv.mynumber, 0) as mynumber
from (
select to_char(date '1970-01-01'
+ numtoyminterval(level - 1, 'month'), 'mm') as month
from dual
connect by level <= 12) months
cross join (
select distinct mycost
from myoracle_mv) costs
left join myoracle_mv mv
on mv.month = months.month
and mv.mycost = costs.mycost
order by months.month, costs.mycost, mv.mynumber;
i daje:
MONTH MYCOST MYNUMBER
----- ------ ----------
01 AAA 3777.24
01 BBB 18811
01 CCC 3845.47
01 DDD 0
02 AAA 49973.12
02 BBB 29872.67
02 CCC 3050.54
02 DDD 0
03 AAA 4049.91
03 BBB 29068.55
03 CCC 3784.44
03 DDD 107.07
04 AAA 469.485
04 BBB 264957.8
04 CCC 799.73
04 DDD 181.78
05 AAA 5872.22
05 BBB 67673
05 CCC 124884.2
05 DDD 110.09
06 AAA 65837.71
06 BBB 855.02
06 CCC 5157.24
06 DDD 18016.19
07 AAA 566.23
07 BBB 5226.1
07 CCC 19184.78
07 DDD 1772.95
08 AAA 18432.95
08 BBB 2663.24
08 CCC 2280.05
08 DDD 63.32
09 AAA 0
09 BBB 0
09 CCC 0
09 DDD 0
10 AAA 0
10 BBB 0
10 CCC 0
10 DDD 0
11 AAA 0
11 BBB 0
11 CCC 0
11 DDD 0
12 AAA 4337.75
12 BBB 5490.58
12 CCC 0
12 DDD 0
48 rows selected
Ale miejmy nadzieję, że masz inną tabelę, która zawiera możliwy mycost
wartości (zakładając, że reprezentują one coś w rodzaju centrum kosztów, a nie cenę; nieco trudno powiedzieć, co jest jakie) i możesz ich użyć zamiast podzapytania.
Pamiętaj też, że jeśli chcesz dodać filtr, np. aby ograniczyć dane do określonego roku, musisz to zrobić w left join
klauzula, a nie jako where
lub przywróciłbyś sprzężenie zewnętrzne na wewnętrzne. Na przykład dodanie tego
:
where mv.year = 2011
oznaczałoby, że wróciły tylko dwa wiersze:
MONTH MYCOST MYNUMBER
----- ------ ----------
12 AAA 4337.75
12 BBB 5490.58
Ale jeśli ustawiłeś inny warunek na zewnętrznym sprzężeniu nadal otrzymasz 48 wierszy z powrotem, z których 46 ma zera, a dwa wartości powyżej:
...
left join myoracle_mv mv
on mv.month = months.month
and mv.mycost = costs.mycost
and mv.year = 2011
order by months.month, costs.mycost, mv.mynumber;
...
11 CCC 0
11 DDD 0
12 AAA 4337.75
12 BBB 5490.58
12 CCC 0
12 DDD 0
48 rows selected