如何使用最新日期更新除最后 5 行以外的所有行的标志?
How to update a flag for all rows except the last 5 with the latest dates?
我有一个 DB2 LUW 9.7 table 看起来像这样(更新前):
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,并将时间戳列 Dttm 设置为 8/3/2018 8:30:00.000000 AM。现在 table 看起来像这样:
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
我想编写一个更新查询,将 table 中所有列的 New_Flag 列设置为 0,但最近日期为 5 的列除外:ID #1,# 5、#2、#7,以及#4 或#6。第5条记录选#4还是#6都无所谓,只要返回5条即可。
这就是 table 最终的样子(我任意选择 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 查询中执行此操作(最好不要在存储过程中执行)?有没有更有效的方法来实现我想要完成的目标?
谢谢。
我想你可以用 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
);
虽然 Gordon 的回答不是很准确,但他确实帮助我走上了正确的道路。
这是我想出的解决方案:
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 个最近的记录之一更新,它将被忽略。
这将适用于最新版本的 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
我有一个 DB2 LUW 9.7 table 看起来像这样(更新前):
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,并将时间戳列 Dttm 设置为 8/3/2018 8:30:00.000000 AM。现在 table 看起来像这样:
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
我想编写一个更新查询,将 table 中所有列的 New_Flag 列设置为 0,但最近日期为 5 的列除外:ID #1,# 5、#2、#7,以及#4 或#6。第5条记录选#4还是#6都无所谓,只要返回5条即可。
这就是 table 最终的样子(我任意选择 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 查询中执行此操作(最好不要在存储过程中执行)?有没有更有效的方法来实现我想要完成的目标?
谢谢。
我想你可以用 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
);
虽然 Gordon 的回答不是很准确,但他确实帮助我走上了正确的道路。
这是我想出的解决方案:
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 个最近的记录之一更新,它将被忽略。
这将适用于最新版本的 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