我的表中有以下数据:
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中的更新查询?
答案 0 :(得分:1)
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;
再次执行相同的更新以更新第3行状态。 如果没有。行是可变的,那么你将不得不修改查询。
答案 1 :(得分:0)
以下内容应该为您解决问题:
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_cd
的记录。它在日期中加入查找具有type_cd
并且end_dt
小于当前记录end_dt
的任何记录。
最后的QUALIFY
窗口函数会查找type_cd
具有最高end_dt
的记录。这里的缺点是你的表越大,你在连接中产生的记录就越多,所以你的中间结果会大幅增长。您的结果将是正确的,但您将占用越来越多的假脱机空间。
如果您在此查询中发现难以理解窗口函数,请尝试在不使用SELECT *
的情况下运行查询。您可以更轻松地完成QUALIFY
逻辑。
答案 2 :(得分:0)
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
答案 3 :(得分:0)
填充这些NULL对于LAST_VALUE
来说是一项简单的任务:
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