在oracle sql中更新倒数第二条记录
我有3把主键。公司名称,EmpNo,起始日期 我想创建一个存储过程,允许我只更新每个empno的倒数第二条记录。我怎样才能做到这一点?在这种情况下,我必须按照empnno更新记录,但我只想更新倒数第二个记录,而不考虑记录的数量 前任;如果我有100条记录,我想更新同一个empno的第99条记录在oracle sql中更新倒数第二条记录,sql,oracle,top-n,Sql,Oracle,Top N,我有3把主键。公司名称,EmpNo,起始日期 我想创建一个存储过程,允许我只更新每个empno的倒数第二条记录。我怎样才能做到这一点?在这种情况下,我必须按照empnno更新记录,但我只想更新倒数第二个记录,而不考虑记录的数量 前任;如果我有100条记录,我想更新同一个empno的第99条记录 CompanyNo EmpNo StartDate FinalDate 1 1 1999/01/01 2013/04/26 1 1
CompanyNo EmpNo StartDate FinalDate
1 1 1999/01/01 2013/04/26
1 1 2013/04/17 9999/12/31
1 2 1999/01/0 2013/04/26
1 2 2013/04/17 9999/12/31
1 3 1999/01/01 2013/04/26
1 3 2013/04/17 9999/12/31
在这种情况下,我只想编辑FinalDate中倒数第二个。
这些,
CompanyNo EmpNo StartDate FinalDate
1 1 1999/01/01 2013/04/26 <--- this finaldate field
1 2 1999/01/01 2013/04/26 <--- this finaldate field
1 3 1999/01/01 2013/04/26 <--- this finaldate field
CompanyNo EmpNo StartDate FinalDate
1 1999/01/01 2013/04/26Oracle提供了一个称为查询的伪列。因此,如果您知道数据集的总大小(计算它),您可以使用ROWNUM访问倒数第二行,获取主键值并正确更新它。假设您想要什么,您可以通过以下方式获得每个empno/公司的第二个最终日期
SELECT empNo FROM
(
SELECT companyName, empNo, rank() over (PARTITION BY companyName,empNo
ORDER BY FinalDate DESC) as rankings FROM yourTable
) WHERE ranking = 2
你可以做任何你需要的更新
Update yourTable set something = something WHERE empNo IN ( thatQueryAbove)
我不明白你为什么需要一个存储过程。您所描述的内容只需一句话:
merge into employment emp
using
(
select CompanyName,
empno,
startdate,
finaldate,
row_number() over (partition by CompanyName, EmpNo order by StartDate desc) as rnk
from employment
) t on (t.companyname = emp.companyname and t.empno = emp.empno and t.startdate = emp.startdate and t.rnk = 2)
when matched then update
set finaldate = date '2013-04-28';
这将把这些行的最终日期更改为'2013-04-28'
尽管我不得不承认,我不明白您真正想做什么。您的主键如何表示记录的顺序?您使用“编辑行”的确切含义是什么?是否要阻止另一个服务器上的更新?那一行你到底想更新什么?我试着按ASC排序我的3个主键,然后试着使用行号,但可能我遗漏了什么。我编辑了我的问题。道歉。也许需要更明确一些。提前谢谢。@a_horse_和_no_名称用于在多个列上进行分区,是否需要将每个列名括在括号中?@a_horse和_no_名称您是对的,但我很确定它是括号。也许括号也可以。我想编辑每个员工的倒数第二条记录。今天晚些时候我会尝试修改你的代码。@Edu:“编辑”这个词在SQL中没有任何意义。您可以更新、删除或插入行。你不能“编辑”它们。我在评论你的代码时弄错了,但我在标题中使用了“更新”一词。很抱歉给你带来了困惑。