sql >> データベース >  >> RDS >> Oracle

Oracle:すべての月のデータを取得します。データがない場合は0です。

    既存の回答と非常に似ていますが、これは次のとおりです。

    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;
    

    あなたが投稿したデータでこれを与えます:

    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
    

    mynumberにゼロを表示したい場合 列を作成すると、次のようになります。

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

    これにより:

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

    Jafarの回答に対するコメントから、おそらくあなたは自分でそこまで到達したように思えますが、すべてのmycostにゼロの値が必要です。 すべての月の値。その場合は、mycostの可能な値のリストを取得する必要があります それに外側も結合します。これは、すでに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;
    

    そして与える:

    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 
    

    しかし、うまくいけば、可能なmycostを保持する別のテーブルがあります 値(価格ではなくコストセンターのようなものを表していると仮定します。何が何であるかを判断するのは少し難しいです)。サブクエリの代わりにそれを使用できます。

    SQLフィドル

    フィルタを追加したい場合は、たとえば、データを特定の年に制限するには、left joinでそれを行う必要があります whereとしてではなく句 または、外側の結合を内側の結合に戻します。たとえば、これを追加 します。 :

    where mv.year = 2011
    

    つまり、2行しか戻ってこないということです:

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

    ただし、外部結合の別の条件よりも作成した場合 それでも48行が返され、そのうち46行はゼロで、2行は上記の値です。

    ...
    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. MySQL Workbench:警告を表示する方法は?

    2. PHP / PDO:文字列値を含む行を検索するためのSQl

    3. グループごとに最も頻繁に使用されるMySQLSELECT

    4. Mysql類似データのintの自動インクリメント