Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

Oracle:Nhận dữ liệu trên tất cả các tháng, 0 nếu không có dữ liệu

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.

SQL Fiddle .

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 


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. NLS_CHARSET_DECL_LEN () Hàm trong Oracle

  2. Tình huống nào khiến các gói Oracle trở nên không hợp lệ?

  3. Bộ sưu tập PL / SQL:Bảng lồng nhau trong cơ sở dữ liệu Oracle

  4. Làm thế nào để chọn một nhà cung cấp Oracle cho ứng dụng .Net?

  5. Không thể tham gia giao dịch phân tán với NHibernate