Sangat mirip dengan jawaban yang ada, tetapi ini:
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;
memberikan ini dengan data yang Anda posting:
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
Jika Anda ingin angka nol muncul di mynumber
kolom maka Anda dapat membuatnya:
select months.month, mv.mycost, coalesce(mv.mynumber, 0) as mynumber
yang memberikan:
...
08 DDD 63.32
09 0
10 0
11 0
12 AAA 4337.75
...
Dari komentar pada jawaban Jafar, sepertinya Anda sudah sejauh itu sendiri tetapi Anda ingin nilai nol untuk semua mycost
nilai untuk semua bulan. Jika demikian, maka Anda perlu mendapatkan daftar kemungkinan nilai untuk mycost
dan luar bergabung dengan itu juga. Ini mengambil semua nilai yang sudah ada di 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;
dan memberikan:
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
Tapi mudah-mudahan Anda memiliki tabel lain yang menyimpan kemungkinan mycost
nilai (dengan asumsi itu mewakili sesuatu seperti pusat biaya, bukan harga; agak sulit untuk mengatakan apa itu) dan Anda dapat menggunakannya sebagai ganti subkueri.
Perhatikan juga bahwa jika Anda ingin menambahkan filter, mis. untuk membatasi data ke tahun tertentu, Anda harus melakukannya di left join
klausa, bukan sebagai where
klausa, atau Anda akan mengembalikan gabungan luar ke dalam. Misalnya, menambahkan ini
:
where mv.year = 2011
berarti Anda hanya mendapatkan kembali dua baris:
MONTH MYCOST MYNUMBER
----- ------ ----------
12 AAA 4337.75
12 BBB 5490.58
Tetapi jika Anda membuat dari kondisi lain di luar join Anda masih akan mendapatkan 48 baris kembali, 46 di antaranya memiliki nol dan dua memiliki nilai di atas:
...
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