在oracle sql中更新倒数第二条记录

在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

我有3把主键。公司名称,EmpNo,起始日期

我想创建一个存储过程,允许我只更新每个empno的倒数第二条记录。我怎样才能做到这一点?在这种情况下,我必须按照empnno更新记录,但我只想更新倒数第二个记录,而不考虑记录的数量 前任;如果我有100条记录,我想更新同一个empno的第99条记录

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中没有任何意义。您可以更新、删除或插入行。你不能“编辑”它们。我在评论你的代码时弄错了,但我在标题中使用了“更新”一词。很抱歉给你带来了困惑。