2017-09-22 13 views
1

私はOracleの小さな問題に対処しなければならない...私は2列のテーブルを持っている、最初の列には日付が含まれ、2番目にはインポートが含まれています。 「インポート列」には、NULL値またはNULL値以外の値を指定できます。 私がしたいのは、日付列(これは簡単です:)で注文してから、「インポート列」内の連続したNULLまたはNULL値ではないブロックでテーブルを分割し、ブロックに番号を付ける3番目の列を追加することです。 例:Oracle - インデックス付きブロック内のテーブルを分割

Date  Import 
01/01/2017 99.12 
01/02/2017 18.19 
01/03/2017 22.92 
01/04/2017 28.10 
01/05/2017 
01/06/2017 
01/07/2017 
01/08/2017 33.78 
01/09/2017 20.30 
01/10/2017 12.33 
01/11/2017 
01/12/2017 1.68 

この表では、あなたがこのような分析関数を使用することができます

Date  Import Block 
01/01/2017 99.12 1 
01/02/2017 18.19 1 
01/03/2017 22.92 1 
01/04/2017 28.10 1 
01/05/2017   2 
01/06/2017   2 
01/07/2017   2 
01/08/2017 33.78 3 
01/09/2017 20.30 3 
01/10/2017 12.33 3 
01/11/2017   4 
01/12/2017 1.68 5 

答えて

1

になったはずです。

select d, import, sum(state_change) over (order by d) as block 
    from 
(
    select d, import, import_state, 
     case when import_state = lag(import_state) over (order by d, import) 
       then 0 else 1 end state_change 
    from 
    (
    select d, import, case when import is not null then 1 else 0 end as import_state 
     from t 
) 
); 

を(NB DATEが予約されているように私はDにあなたのDATE列に改称ワード)。最も内側のクエリで始まる、それを破壊

select d, import, case when import is not null then 1 else 0 end as import_state 
    from t 

これがnullの場合importがnull、0でないとき1である列import_stateが追加されます。これにより、ブロックが作成されますが、1,2,3,4、...の代わりに1,0,1,0、...が割り当てられます。

次の部分では、それぞれ前の行にあるimport_stateと、変更を確認します。列state_changeは、変更があった場合は1、それ以外の場合は0です。したがって、各ブロックの最初の行には1があり、リセットには0があります。

外側部分は単にstate_changeの値を累積的に合計します必要な結果。

さらに簡単な解決策があります。