2016-07-15 3 views
0

"period_id_group"なんらかの種類の新しい列を追加するために、以下のデータセットにクエリを書き込もうとしています。私が取得しようとしている何連続した範囲を確認するクエリ

contiguous new_period row_nr new_period_starting_id 
0   0   1  0 
1   1   2  2 
1   0   3  0 
1   0   4  0 
1   1   5  5 
1   0   6  0 

は次のとおりです。

contiguous new_period row_nr new_period_starting_id period_id_group 
0   0   1  0       0 
1   1   2  2       2 
1   0   3  0       2 
1   0   4  0       2 
1   1   5  5       5 
1   0   6  0       5 

ロジックがnew_period_starting_idの各0値のために、それは上の行から>0値を取得しなければならないことです。 row_nr = 1ためだから

、何行がその前に存在しないので、period_id_groupこれは(new_period = 1でマーク)新しいperidあるので、period_id_group 2(この行のID)であるrow_nr = 2について0

あります。それは連続した範囲の一部(contiguous = 1ので)ですが、それはnew_period(new_period = 0)、そのperiod_id_groupがある(前の行から値を継承する必要がありませんので、範囲の開始ないのでrow_nr = 3について

連続した範囲の開始) - この場合はperiod_id_group = 2もあります。

私は複数のバージョンを試しましたが、LAG()を使用できないため、SQL Server 2008R2の優れたソリューションを手に入れることができませんでした。私が持っているもの

は、これまでのところ、恥ずべきである:

select * 
from #temp2 t1 
left join (select distinct new_period_starting_id from #temp2) t2 
    on t1.new_period_starting_id >= t2.new_period_starting_id 
where 1 = case 
      when contiguous = 0 
       then 1 
      when contiguous = 1 and t2.new_period_starting_id > 0 
       then 1 
      else 1 
     end 
order by t1.rn 

サンプルデータスクリプト:

declare @tmp2 table (contiguous int 
        , new_period int 
        , row_nr int 
        , new_period_starting_id int); 

insert into @tmp2 values (0, 0, 1, 0) 
         , (1, 1, 2, 2) 
         , (1, 0, 3, 0) 
         , (1, 0, 4, 0) 
         , (1, 1, 5, 5) 
         , (1, 0, 6, 0); 

すべてのヘルプは高く評価されます。

+0

@yatinparab最新の質問 –

答えて

0

select t1.contiguous 
    , t1.new_period 
    , t1.row_nr 
    , t1.new_period_starting_id 
    , x.new_period_starting_id 
from @tmp2 t1 
outer apply 
(
    select top 1 * 
    from @tmp2 t2 
    where (t2.row_nr = 1 
     or t2.new_period_starting_id > 0) 
     and t1.row_nr >= t2.row_nr 
    order by t2.row_nr desc 
) x 
1

あなたが正しく理解している場合、追加の列が1つ必要です。

select * 
    , case 
     when contiguous = 0 
      then f1 
     when contiguous = 1 and new_periods = 1 
      then f1 
     when contiguous = 1 and new_periods = 0 
      then v 
     else NULL 
    end [period_group] 
from (
    select * 
     , (select max(f1) from #temp2 where new_period_starting_id > 0 and rn < t1.rn) [v] 
    from #temp2 t1 
    ) rs 
order by rn 
+1

これは私がちょうどやったことですが、私は答えを得ました。それにもかかわらず、あなたの答えをupvoted –

+0

ありがとう! ORDER BYで「TOP 1」に変更して効率を改善しました。 MAXはこれまでのすべての行を照会する必要がありますが、ORDER BYを使用するTOP 1はわずかな照会しか必要としません。 –

1

ここでは、このためのさらに別のオプションです:解決策が見つかり

SELECT t1.contiguous, t1.new_period, t1.row_nr, t1.new_period_starting_id, 
    (SELECT TOP 1 (new_period_starting_id) 
    FROM YourTable t2 
    WHERE t2.row_nr <= t1.row_nr 
     AND t2.period_id_group > 0 /* optimization */ 
    ORDER BY t2.row_nr DESC /* optimization */) AS period_id_group 
FROM YourTable t1 
関連する問題