我在Cognos中使用SQL。 如果我有一列日期和感兴趣的字段,我如何创建一个新列,其中每行提供最新的不同值。我不相信我可以用滞后来做这件事。谢谢你的任何想法。
Example:
Date Field DesiredNew
1/9/1994 D C
1/8/1994 D C
1/7/1994 D C
1/6/1994 C B
1/5/1994 B A
1/4/1994 B A
1/3/1994 B A
1/2/1994 A
1/1/1994 A
答案 0 :(得分:0)
这只是一个思维敏捷的快速想法。
如果您可以添加两列(不显示它们只是将它们用于逻辑):
Date Field DesiredNew FieldSeq DesicredNewSeq
1/7/1994 D C 4 3
1/6/1994 C B 3 2
因此,您可以使用函数CASE来测试数字和分配字母。
答案 1 :(得分:0)
<强>概述强>
解决方案的要点是两步法。
首先,考虑根据Date
排序的原始记录和具有相同Field
值的连续记录,并记录每个所述组的最大和最小日期。生成的结果集记录描述了字段值不变的最大日期间隔(此选择封装在下面的sql示例中的视图vtest_lag
中)。
接下来自我加入这个新结果集,其日期列之一的延迟为1。这样,相邻区间在最终结果集中配对,允许根据需要更新Field
值。
<强>注意事项强>
SQL解决方案
这个独立的示例与sql方言无关,除了oracle的rownum
伪列,提供结果集中记录的序号。其他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部分:更新
View vtest_lag
封装查询以提供更新语句的数据。
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)
;