Sehr ähnlich zu bestehenden Antworten, aber dies:
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;
gibt dies mit den von Ihnen geposteten Daten aus:
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
Wenn Sie möchten, dass in mynumber
eine Null erscheint Spalte dann kannst du das machen:
select months.month, mv.mycost, coalesce(mv.mynumber, 0) as mynumber
was ergibt:
...
08 DDD 63.32
09 0
10 0
11 0
12 AAA 4337.75
...
Aus den Kommentaren zu Jafars Antwort klingt es so, als wären Sie vielleicht alleine so weit gekommen, aber Sie möchten Nullwerte für alle mycost
Werte für alle Monate. Wenn dies der Fall ist, müssen Sie die Liste der möglichen Werte für mycost
abrufen und äußerer Join dazu. Dies nimmt alle Werte, die bereits im MV sind:
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;
und ergibt:
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
Aber hoffentlich haben Sie eine andere Tabelle, die die möglichen mycost
enthält Werte (vorausgesetzt, es handelt sich eher um eine Kostenstelle als um einen Preis; etwas schwer zu sagen, was was ist), und Sie können diese anstelle der Unterabfrage verwenden.
Beachten Sie auch, dass Sie, wenn Sie einen Filter hinzufügen möchten, z. Um die Daten auf ein bestimmtes Jahr zu beschränken, müssen Sie dies im left join
tun -Klausel, nicht als where
-Klausel, oder Sie würden den äußeren Join in einen inneren zurücksetzen. Beispiel:Hinzufügen
:
where mv.year = 2011
würde bedeuten, dass Sie nur zwei Zeilen zurückbekommen:
MONTH MYCOST MYNUMBER
----- ------ ----------
12 AAA 4337.75
12 BBB 5490.58
Aber wenn Sie als eine andere Bedingung für den äußeren Join gemacht haben Sie würden immer noch 48 Zeilen zurückbekommen, von denen 46 Nullen und zwei die obigen Werte haben:
...
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