2017-12-20 2 views
0

年度にすべての月に対応するレコードを取得するには:どのように私はセットしたOracle

Month id1 id2 id3 value 

Jan-17 1 2 3  67 
Feb-17 2 3 4  43 

がどのように私は年にすべての月に対応する(id1, id2, id3)の組み合わせを得るのですか?

たとえば、私は1月-17から開始する場合は :出力は次のようになります

month id1 id2 id3 value 
jan-17 1 2 3  67 
feb-17 1 2 3  0 
mar-17 1 2 3  0 
apr-17 1 2 3  0 
may-17 1 2 3  0 
jun-17 1 2 3  0 
jul-17 1 2 3  0 
aug-17 1 2 3  0 
sep-17 1 2 3  0 
oct-17 1 2 3  0 
nov-17 1 2 3  0 
dec-17 1 2 3  0 
jan-17 2 3 4  0 
feb-17 2 3 4  43 
mar-17 2 3 4  0 
apr-17 2 3 4  0 
may-17 2 3 4  0 
jun-17 2 3 4  0 
jul-17 2 3 4  0 
aug-17 2 3 4  0 
sep-17 2 3 4  0 
oct-17 2 3 4  0 
nov-17 2 3 4  0 
dec-17 2 3 4  0 
+0

最初のレコードから 'id1 = 1、id2 = 2、id3 = 3'を他のすべての月に複製しますか?なぜあなたは2つのjan-17と2つのfeb17を持っていますか?あなたの欲望のための論理を説明してください。 [** How-to-Ask **](http://stackoverflow.com/help/how-to-ask) \t \t [** START **](http ://spaghettidba.com/2015/04/24/how-to-post-at-sql-question-on-a-public-forum/)質問品質を向上させ、より良い回答を得る方法を学ぼう。 –

+0

詳細情報が必要です。いくつのIDがありますか? – Guru

+0

こんにちは!複数のIDがあります。すべての月に対してIDのそれぞれが存在するようにします – joe

答えて

3

をあなたはとの年のすべての月を生成することができます。

select add_months(date '2017-01-01', level - 1) 
from dual 
connect by level <= 12 

そして、あなたはとIDのすべての組み合わせを得ることができます:

select distinct id1, id2, id3 from your_table 

あなたはすべての月のすべてのIDの組み合わせを取得するためにTHOSを横断-参加することができます:

select month, id1, id2, id3 
from (
    select add_months(date '2017-01-01', level - 1) as month 
    from dual 
    connect by level <= 12 
) 
cross join (
    select distinct id1, id2, id3 from your_table 
) 

あなたのサンプルデータから24行が得られます。次に、あなたのテーブルへは再び任意の値をピックアップすること-参加を残して、一致するものがないときにゼロを使用するようにCOALESCEを使用することができます:あなたが唯一の他の年に現れIDの組み合わせを持っている場合は

with cte (month, id1, id2, id3) as (
    select month, id1, id2, id3 
    from (
    select add_months(date '2017-01-01', level - 1) as month 
    from dual 
    connect by level <= 12 
) 
    cross join (
    select distinct id1, id2, id3 from your_table 
) 
) 
select cte.month, cte.id1, cte.id2, cte.id3, coalesce(t.value, 0) as value 
from cte 
left join your_table t on t.month = cte.month 
and t.id1 = cte.id1 
and t.id2 = cte.id2 
and t.id3 = cte.id3 
order by cte.id1, cte.id2, cte.id3, cte.month; 

MONTH    ID1  ID2  ID3  VALUE 
---------- ---------- ---------- ---------- ---------- 
2017-01-01   1   2   3   67 
2017-02-01   1   2   3   0 
2017-03-01   1   2   3   0 
2017-04-01   1   2   3   0 
2017-05-01   1   2   3   0 
2017-06-01   1   2   3   0 
2017-07-01   1   2   3   0 
2017-08-01   1   2   3   0 
2017-09-01   1   2   3   0 
2017-10-01   1   2   3   0 
2017-11-01   1   2   3   0 
2017-12-01   1   2   3   0 
2017-01-01   2   3   4   0 
2017-02-01   2   3   4   43 
2017-03-01   2   3   4   0 
2017-04-01   2   3   4   0 
2017-05-01   2   3   4   0 
2017-06-01   2   3   4   0 
2017-07-01   2   3   4   0 
2017-08-01   2   3   4   0 
2017-09-01   2   3   4   0 
2017-10-01   2   3   4   0 
2017-11-01   2   3   4   0 
2017-12-01   2   3   4   0 

をそして含まれるものをしたくないあなたはそれのためにフィルタリングするIDクエリを変更することにより、指定された年でいかなるデータを持っているもののみに制限できます。

select distinct id1, id2, id3 from your_table 
where extract(year from month) = 2017 

または

select distinct id1, id2, id3 from your_table 
where month between date '2017-01-01' and date '2017-12-01' 

私はmonthDATEの列であると仮定しています。すべての値は、1か月の最初の日の深夜です。もちろん、表示することもできます。


@boneistが述べたように、10グラム以来、私たちは別工程でこれらのIDを取得するのではなく、partitioned outer joinを使用することができます。同じ結果を取得

with months (month) as (
    select add_months(date '2017-01-01', level - 1) 
    from dual 
    connect by level <= 12 
) 
select m.month, t.id1, t.id2, t.id3, coalesce(t.value, 0) as value 
from months m 
left join your_table t partition by (t.id1, t.id2, t.id3) 
on t.month = m.month 
order by t.id1, t.id2, t.id3, m.month; 

MONTH    ID1  ID2  ID3  VALUE 
---------- ---------- ---------- ---------- ---------- 
2017-01-01   1   2   3   67 
2017-02-01   1   2   3   0 
2017-03-01   1   2   3   0 
... 
2017-01-01   2   3   4   0 
2017-02-01   2   3   4   43 
2017-03-01   2   3   4   0 
... 

をが、はるかに簡単です(そしてテーブルを1回だけヒットするほど効率的です)。

+0

制限は1アップヴォートだけですが、Upvotesのまだトンです.... !!! –

+4

私はパーティション化された外部結合が、別個のIDを見つける必要をなくすことができると思います。 – Boneist

+2

@Boneist - 当然のことながら...私はそれを追加しますが、自分で答えるなら削除します。ありがとう。 –

関連する問題