Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Oracle:Dapatkan data di semua bulan, 0 jika tidak ada data

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.

SQL Fiddle .

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 


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Menampilkan batasan dalam sebuah tabel

  2. Format Tanggal Oracle

  3. Membantu menghitung jumlah kompleks dalam kumpulan data hierarkis

  4. Cari tahu apakah string hanya berisi karakter ASCII

  5. Bagaimana cara mendapatkan jumlah orang berdasarkan kelompok usia menggunakan kueri SQL di database Oracle?