Rất giống với thoát câu trả lời, nhưng điều này:
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;
cung cấp điều này với dữ liệu bạn đã đăng:
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
Nếu bạn muốn số 0 xuất hiện trong mynumber
thì bạn có thể thực hiện điều đó:
select months.month, mv.mycost, coalesce(mv.mynumber, 0) as mynumber
mang lại:
...
08 DDD 63.32
09 0
10 0
11 0
12 AAA 4337.75
...
Từ các nhận xét về câu trả lời của Jafar, có vẻ như có thể bạn đã tự mình đạt được điều đó nhưng bạn muốn có giá trị bằng không cho tất cả mycost
giá trị cho tất cả các tháng. Nếu đúng như vậy thì bạn cần lấy danh sách các giá trị có thể có cho mycost
và tham gia bên ngoài vào đó nữa. Điều này đang lấy tất cả các giá trị đã có trong 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;
và đưa ra:
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
Nhưng hy vọng bạn có một bảng khác chứa mycost
có thể giá trị (giả sử đó là đại diện cho một cái gì đó như trung tâm chi phí, thay vì giá; hơi khó để phân biệt cái gì) và bạn có thể sử dụng giá trị đó thay vì truy vấn con.
Cũng lưu ý rằng nếu bạn muốn thêm bộ lọc, ví dụ:để hạn chế dữ liệu trong một năm cụ thể, bạn cần thực hiện điều đó trong left join
mệnh đề, không phải là where
hoặc bạn sẽ hoàn nguyên kết nối bên ngoài thành một kết nối bên trong. Ví dụ: thêm cái này
:
where mv.year = 2011
có nghĩa là bạn chỉ nhận lại hai hàng:
MONTH MYCOST MYNUMBER
----- ------ ----------
12 AAA 4337.75
12 BBB 5490.58
Nhưng nếu bạn thực hiện hơn một điều kiện khác ở kết nối bên ngoài bạn vẫn nhận được 48 hàng trở lại, với 46 hàng trong số đó có số 0 và hai hàng có giá trị ở trên:
...
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