概要
溶液の要旨は、2段階のアプローチです。
最初に、Date
に基づいて注文された元のレコードと、同じグループの最大日付と最小日付を示す同じField
値を持つ連続するレコードを考慮してください。生成された結果セットのレコードには、フィールド値が変更されない最大の日付間隔が記述されます(この選択は、以下のSQLの例のvtest_lag
ビューにカプセル化されています)。
次に、この新しい結果セットを1のラグその日付列のいずれか。このように、隣接する間隔は所望のようField
値を更新することができ、最終的な結果セットに対になっている。
警告
- は、溶液は、元のデータには重複日付を前提としない
- 溶液を離れ、結果セット内のレコードの序数を供給オラクル
rownum
疑似から効率
SQL溶液
この自己完結型の例は、SQLダイアレクトにとらわれないと関係しません。他のSQLフレーバにも同等の機能があります。
パート1/2:セットアップ
create table test_lag (
t_date date
, field varchar2(10)
, desirednew varchar2(10)
, computednew varchar2(10)
);
insert into test_lag values (to_date ('01/09/1994', 'DD/MM/YYYY'), 'D', 'C' , null);
insert into test_lag values (to_date ('01/08/1994', 'DD/MM/YYYY'), 'D', 'C' , null);
insert into test_lag values (to_date ('01/07/1994', 'DD/MM/YYYY'), 'D', 'C' , null);
insert into test_lag values (to_date ('01/06/1994', 'DD/MM/YYYY'), 'C', 'B' , null);
insert into test_lag values (to_date ('01/05/1994', 'DD/MM/YYYY'), 'B', 'A' , null);
insert into test_lag values (to_date ('01/04/1994', 'DD/MM/YYYY'), 'B', 'A' , null);
insert into test_lag values (to_date ('01/03/1994', 'DD/MM/YYYY'), 'B', 'A' , null);
insert into test_lag values (to_date ('01/02/1994', 'DD/MM/YYYY'), 'A', null , null);
insert into test_lag values (to_date ('01/01/1994', 'DD/MM/YYYY'), 'A', null , null);
パート2/2:更新
ビューvtest_lag
は、UPDATE文のためのデータを提供するクエリをカプセル化します。
create or replace view vtest_lag as
select emb.*
, rownum seq
from (
select *
from (
select sysdate t_date1
, null field1
, t_date t_date2
, field field2
from test_lag
where t_date = (select max(t_date) from test_lag)
union all
select t_date t_date1
, field field1
, to_date('01/01/1900', 'DD/MM/YYYY')
t_date2
, null field2
from test_lag
where t_date = (select min(t_date) from test_lag)
union all
select po1.t_date t_date1
, po1.field field1
, po2.t_date t_date2
, po2.field field2
from (
select po1_base.*
, rownum seq
from (
select *
from test_lag
order by t_date desc
) po1_base
) po1
join (
select po2_base.*
, rownum seq
from (
select *
from test_lag
order by t_date desc
) po2_base
) po2
on po2.seq = po1.seq + 1
where po1.field <> po2.field
)
order by t_date1 desc
) emb
;
update test_lag trg
set trg.computednew = (select v2.field2 from vtest_lag v1 join vtest_lag v2 on v2.seq = v1.seq+1 where trg.t_date <= v1.t_date2 and trg.t_date >= v2.t_date1)
;
ありがとうございます。私のデータはより複雑で、繰り返しの日付も含まれ、別のシーケンスフィールドもあります。私はあなたの答えを見て、それを大いに感謝します。コンパクトなソリューションが存在するようには見えないので、データをRにインポートすると、簡単に操作できます: – Patrick
out。(dat [i、2] == dat [0:0]の場合)[ の場合、{iは1:nrow(dat)}のための のための{ のために、 (i、j)、2]) out.i [[i]] < - data.frame(dat [i、j)、2])= }他{ out.i [[I] < - data.frame(DAT [I、]、DAT [MAX(i、j)は、2])} }} OUTI < - DO Outl [3] < - ifelse(outi [、2] == outi [、3]、 ""、as.character).call(rbind、out.i) colnames(outi)[3] < - "FieldNew" outi [3] (outi [、3])) – Patrick