2015-04-06 30 views
-1

我有以下数据在我的表:更新在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 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

您可能想阅读[我如何问一个好问题](http://stackoverflow.com/help/how-to-ask),这增强了获得一个可能性有用答案_drastically_。你可能会发现[ESR](https://en.m.wikipedia.org/wiki/Eric_S._Raymond)的优秀论文[如何提问智能方式](http://catb.org/~esr/) faqs/smart-questions.html)也很有帮助。 – 2015-04-09 12:48:54

回答

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_cdend_dt小于当前记录end_dt的记录。

QUALIFY窗口功能在最后查找具有最高end_dttype_cd的记录。这里的缺点是你的表越大,你在连接中产生的记录就越多,所以你的中间结果将会大大增加。你的结果是正确的,但是你将会占用越来越多的假脱机空间。

如果您发现此查询中的窗口功能难以理解,请尝试运行没有它的查询和SELECT *。那么你可以通过QUALIFY逻辑稍微简单一点。

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行状态。 如果没有。的行是可变的,那么你将不得不修改查询。

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 
0

填补这些空值是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 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