Velmi podobné existujícím odpovědím, ale toto:
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;
dává toto s daty, které jste odeslali:
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
Pokud chcete, aby se v mynumber
objevila nula sloupec, pak to můžete udělat:
select months.month, mv.mycost, coalesce(mv.mynumber, 0) as mynumber
což dává:
...
08 DDD 63.32
09 0
10 0
11 0
12 AAA 4337.75
...
Z komentářů k Jafarově odpovědi to zní, jako byste se možná dostali tak daleko sami, ale chcete nulové hodnoty pro všechny mycost
hodnoty za všechny měsíce. Pokud je tomu tak, musíte získat seznam možných hodnot pro mycost
a vnější se k tomu také připojují. Toto přebírá všechny hodnoty, které jsou již v 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;
a dává:
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 doufejme, že máte jinou tabulku, která obsahuje possble mycost
hodnoty (za předpokladu, že to představuje něco jako nákladové středisko, spíše než cenu; trochu těžko říct, co je co) a můžete to použít místo dílčího dotazu.
Všimněte si také, že pokud byste chtěli přidat filtr, např. Chcete-li omezit data na konkrétní rok, musíte to udělat v left join
klauzule, nikoli jako where
klauzule, nebo byste změnili vnější spojení na vnitřní. Například přidání tohoto
:
where mv.year = 2011
znamenalo by to, že jste dostali zpět pouze dva řádky:
MONTH MYCOST MYNUMBER
----- ------ ----------
12 AAA 4337.75
12 BBB 5490.58
Ale pokud jste udělali další podmínku na vnějším spojení stále dostanete 48 řádků zpět, přičemž 46 z nich má nuly a dva mají hodnoty výše:
...
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