Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Oracle:Uzyskaj dane ze wszystkich miesięcy, 0 jeśli brak danych

Bardzo podobne do istniejących odpowiedzi, ale to:

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;

daje to wraz z opublikowanymi danymi:

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

Jeśli chcesz, aby zero pojawiło się w mynumber kolumna, możesz to zrobić:

select months.month, mv.mycost, coalesce(mv.mynumber, 0) as mynumber

co daje:

...
08    DDD         63.32 
09                    0 
10                    0 
11                    0 
12    AAA       4337.75 
...

Z komentarzy do odpowiedzi Jafara wydaje się, że być może sam zaszedłeś tak daleko, ale chcesz zerowych wartości dla wszystkich mycost wartości dla wszystkich miesięcy. Jeśli tak jest, musisz uzyskać listę możliwych wartości dla mycost i zewnętrzne dołączenie do tego. Pobiera to wszystkie wartości, które są już w 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;

i daje:

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 

Ale miejmy nadzieję, że masz inną tabelę, która zawiera możliwy mycost wartości (zakładając, że reprezentują one coś w rodzaju centrum kosztów, a nie cenę; nieco trudno powiedzieć, co jest jakie) i możesz ich użyć zamiast podzapytania.

Skrzypce SQL .

Pamiętaj też, że jeśli chcesz dodać filtr, np. aby ograniczyć dane do określonego roku, musisz to zrobić w left join klauzula, a nie jako where lub przywróciłbyś sprzężenie zewnętrzne na wewnętrzne. Na przykład dodanie tego :

where mv.year = 2011

oznaczałoby, że wróciły tylko dwa wiersze:

MONTH MYCOST   MYNUMBER
----- ------ ----------
12    AAA       4337.75 
12    BBB       5490.58 

Ale jeśli ustawiłeś inny warunek na zewnętrznym sprzężeniu nadal otrzymasz 48 wierszy z powrotem, z których 46 ma zera, a dwa wartości powyżej:

...
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. Trzeba zresetować wartość sekwencji w Oracle

  2. Jak włączyć XA Oracle 11g?

  3. Zwróć wiersz z maksymalną wartością jednej kolumny na grupę

  4. Pobieranie ostatniego dnia poprzedniego miesiąca w funkcji Oracle

  5. PL/SQL Online MCQ Quiz