我有一个DB2 LUW 9.7表,看起来像这样(更新之前):
Id SubId Name New_Flag Dttm
-----------------------------------------------------------------------
1 2 Sam 0 5/31/2017 1:30:00.000000 PM
2 3 Joe 1 4/25/2018 12:30:00.000000 PM
3 4 Ann 1 4/3/2018 2:10:00.000000 PM
4 5 Tim 1 4/3/2018 2:15:00.000000 PM
5 6 Tom 0 3/6/2017 2:00:00.000000 PM
6 7 Art 1 4/3/2018 2:15:00.000000 PM
7 8 Jen 1 4/25/2018 12:30:00.000000 PM
8 9 Jim 1 4/3/2018 2:10:00.000000 PM
....many more records where New_Flag = 0
因此,我将ID#1和#5的New_Flag列更新为等于1,并将timestamp列Dttm设置为8/3/2018 8:30:00.000000 AM。现在表看起来像这样:
Id SubId Name New_Flag Dttm
-----------------------------------------------------------------------
1 2 Sam 1 8/3/2018 8:30:00.000000 AM
2 3 Joe 1 4/25/2018 12:30:00.000000 PM
3 4 Ann 1 4/3/2018 2:10:00.000000 PM
4 5 Tim 1 4/3/2018 2:15:00.000000 PM
5 6 Tom 1 8/3/2018 8:30:00.000000 AM
6 7 Art 1 4/3/2018 2:15:00.000000 PM
7 8 Jen 1 4/25/2018 12:30:00.000000 PM
8 9 Jim 1 4/3/2018 2:10:00.000000 PM
....many more records where New_Flag = 0
我想编写一个更新查询,该查询会将表中所有列的New_Flag列设置为等于0,但最新日期为5的除外:ID#1,#5,#2,#7,或者#4或#6。选择#4或#6作为第五条记录并不重要,只要返回5条记录即可。
这就是表的最终外观(我随意选择ID#6作为将New_Flag设置为0的记录之一):
Id SubId Name New_Flag Dttm
-----------------------------------------------------------------------
1 2 Sam 1 8/3/2018 8:30:00.000000 AM
2 3 Joe 1 4/25/2018 12:30:00.000000 PM
3 4 Ann 0 4/3/2018 2:10:00.000000 PM
4 5 Tim 1 4/3/2018 2:15:00.000000 PM
5 6 Tom 1 8/3/2018 8:30:00.000000 AM
6 7 Art 0 4/3/2018 2:15:00.000000 PM
7 8 Jen 1 4/25/2018 12:30:00.000000 PM
8 9 Jim 0 4/3/2018 2:10:00.000000 PM
....many more records where New_Flag = 0
我编写了以下代码来获取5条记录,但是我很难将其转换为UPDATE查询,该查询会将除这5条记录之外的每一行的New_Flag列设置为0:
select distinct
name,
older
from
(
select
t1.name,
t1.dttm as older
from
myTable t1
left outer join
myTable y1 on
y1.new_flag = t1.new_flag
and y1.dttm < t1.dttm
where
t1.new_flag = 1
order by
2 desc
)
fetch first 5 rows only
;
是否可以在UPDATE查询中执行此操作(最好不在存储过程中执行此操作)?有没有更有效的方法来实现我要完成的任务?
谢谢。
答案 0 :(得分:0)
我认为您可以使用fetch
/ offset
来做到这一点:
update mytable
set flag = 0
where dttm < (select t2.dttm
from mytable t2
order by t2.dttm desc
offset 4 fetch first 1 row only
);
编辑:
如果以上版本在您的版本中不起作用,则可能是这样:
update mytable
set flag = 0
where dttm < (select t2.dttm
from (select t2.*, row_number() over (order by t2.dttm desc) as seqnum
from mytable t2
) t2
where seqnum = 5
);
答案 1 :(得分:0)
虽然戈登的答案还不是很明确,但他确实帮助我走上了正确的道路。
这是我想出的解决方案:
update myTable t1
set new_flag = 0
where not exists (
select
1
from
(
select
st2.*,
row_number() over (order by st2.dttm desc) as seqnum
from
myTable st2
where
new_flag = 1
) t2
where
seqnum <= 5
and t1.name = t2.name
);
这应该确保,如果一条记录的New_Flag = 0且Dttm比最新的前5条记录之一更新,则它将被忽略。
答案 2 :(得分:0)
这将在最新版本的Db2 LUW上运行,并且可以说是实现所需目标的最简洁的方法
update
( select
new_flag
from
( select
new_flag
, row_number() over (order by dttm desc) as seqnum
from
myTable t
)
where
seqnum <= 5
and new_flag <> 0
)
set new_flag = 0