Teradata中的更新
我的表格中有以下数据:Teradata中的更新,teradata,Teradata,我的表格中有以下数据: eff_dt end_dt type_cd status 1-Jan-14 5-Jan-14 AAA 0 5-Jan-14 7-Jan-14 null 1 7-Jan-14 10-Jan-14 null 1 10-Jan-14 15-Jan-14 BBB 0 15-Jan-14 21-Jan-14 null 1 21-Jan-14 25-Jan-14 null
eff_dt end_dt type_cd status
1-Jan-14 5-Jan-14 AAA 0
5-Jan-14 7-Jan-14 null 1
7-Jan-14 10-Jan-14 null 1
10-Jan-14 15-Jan-14 BBB 0
15-Jan-14 21-Jan-14 null 1
21-Jan-14 25-Jan-14 null 1
25-Jan-14 30-Jan-14 CCC 0
我想使用自联接更新数据
更新后的表应如下所示:
eff_dt end_dt type_cd status
1-Jan-14 5-Jan-14 AAA 0
5-Jan-14 7-Jan-14 AAA 1
7-Jan-14 10-Jan-14 AAA 1
10-Jan-14 15-Jan-14 BBB 0
15-Jan-14 21-Jan-14 BBB 1
21-Jan-14 25-Jan-14 BBB 1
25-Jan-14 30-Jan-14 CCC 0
请帮助我使用teradata中的更新查询?类似于以下内容的内容应该可以帮到您:
SELECT
t1.eff_dt, t1.end_dt, t2.type_cd, t1.status
FROM
yourtable t1
LEFT OUTER JOIN (SELECT * FROM yourtable WHERE status = 0) t2 ON t1.end_dt >= t2.end_dt
QUALIFY ROW_NUMBER() OVER (PARTITION BY t1.end_dt ORDER BY t2.end_dt DESC) = 1
这是将您的表连接到表的一个版本,其中只存在status=0
记录,因为这些记录具有非空type\u cd
。它在日期加入,查找具有type\u cd
的任何记录,并且end\u dt
小于当前记录end\u dt
末尾的QUALIFY
窗口功能查找具有type\u cd
且end\u dt最高的记录。这里的缺点是,表越大,在联接中生成的记录就越多,因此中间结果将大幅增长。您的结果将是正确的,但会占用越来越多的假脱机空间
如果您发现此查询中的窗口功能难以理解,请尝试在不使用它的情况下运行查询,然后选择*
。您可以更轻松地完成限定
逻辑
eff_dt end_dt type_cd status
1-Jan-14 5-Jan-14 AAA 0
5-Jan-14 7-Jan-14 null 1
7-Jan-14 10-Jan-14 null 1
10-Jan-14 15-Jan-14 BBB 0
15-Jan-14 21-Jan-14 null 1
21-Jan-14 25-Jan-14 null 1
25-Jan-14 30-Jan-14 CCC 0
根据以上数据,我们可以使用状态和日期进行自连接。
第一行的end_dt基本上是第二行的eff_dt
UPDATE A
FROM DB.TABLEA AS A, DB.TABLEA AS B
SET type_cd = B.type_cd
WHERE A.eff_dt = B.end_dt
and A.status = 1;
再次执行相同的更新以更新第三行状态。
如果行数是可变的,则必须修改查询。填充这些空值对于最后一个值来说是一项简单的任务:
create table sample_1
(
eff_dt date,
end_dt date,
type_cd varchar(4)
,status int
);
insert into sample_1(date '2014-01-01',date '2014-01-05','aaa',0);
insert into sample_1(date '2014-01-05',date '2014-01-07',null,1);
insert into sample_1(date '2014-01-07',date '2014-01-10',null,1);
insert into sample_1(date '2014-01-10',date '2014-01-15','bbb',0);
insert into sample_1(date '2014-01-15',date '2014-01-21',null,1);
insert into sample_1(date '2014-01-21',date '2014-01-25',null,1);
insert into sample_1(date '2014-01-25',date '2014-01-30','ccc',0);
upd tgt
from sample_1 tgt
, (
sel tgt.eff_dt,tgt.end_dt,lkp.type_cd,tgt.status
from sample_1 tgt,
(
sel tgt.*,max(eff_dt) over (order by eff_dt asc rows between 1 following and 1 following ) eff_dt1
from sample_1 tgt
where status=0 --type_cd is not null
) lkp
where tgt.eff_dt between lkp.eff_dt and coalesce (eff_dt1,date '9999-12-31')
and coalesce ( tgt.type_cd,lkp.type_cd) =lkp.type_cd
) lkp
set type_cd=lkp.type_cd
where tgt.eff_dt=lkp.eff_dt
UPDATE tgt
FROM mytable tgt
,(
SEL eff_dt,
Last_Value(type_cd IGNORE NULLS)
Over (ORDER BY eff_dt) AS last_cd
FROM mytable
QUALIFY type_cd IS NULL
) AS src
SET type_cd = src.last_cd
WHERE tgt.eff_dt= src.eff_dt
假设这只是一个示例,并且您必须对一组行执行此操作,您最好使用MERGE,它永远不会变慢,但可能会变快:
MERGE INTO mytable AS tgt
USING
(
SEL eff_dt,
Last_Value(type_cd IGNORE NULLS)
Over (ORDER BY eff_dt) AS last_cd
FROM mytable
QUALIFY type_cd IS NULL
) AS src
-- ON must include at least all (P)PI columns of the target table
ON tgt.eff_dt = src.eff_dt
WHEN MATCHED THEN
UPDATE SET type_cd = src.last_cd
你可能想要阅读,这大大提高了获得有用答案的可能性。你可能会发现他的优秀论文也很有帮助。