根据日期修改第二个重复记录

时间:2017-10-03 14:46:47

标签: sql

我有以下数据库:

Invoice_id | Invoice_date

111     | 2017-10-05   
222     | 2017-10-01  
222     | 2017-10-02  
333     | 2017-10-26  
444     | 2017-11-16  
555     | 2017-11-02  
666     | 2017-09-03  
777     | 2017-07-30  
777     | 2017-07-31  
888     | 2017-12-04

这就是我需要的:

对于所有重复值(具有相同的Invoice_id),将最新的值(具有最新日期的值)更改为InvoiceID ++ 1;

示例:如果Invoice_id = 222显示两次,则需要将具有最新日期的重复记录(在本例中为2017-10-02)更新为223的Invoice_id。

2 个答案:

答案 0 :(得分:3)

假设你不关心碰撞,你可以很容易地用ROW_NUMBER做到这一点。

if OBJECT_ID('tempdb..#Something') is not null
    drop table #Something

create table #Something
(
    Invoice_id int
    , Invoice_date date
)

insert #Something values
(111, '2017-10-05')
, (222, '2017-10-01')
, (222, '2017-10-02')
, (333, '2017-10-26')
, (444, '2017-11-16')
, (555, '2017-11-02')
, (666, '2017-09-03')
, (777, '2017-07-30')
, (777, '2017-07-31')
, (888, '2017-12-04');

with SortedResults as
(
    select *
        , RowNum = ROW_NUMBER() over(partition by Invoice_id order by Invoice_date)
    from #Something
)

update SortedResults
set Invoice_id = Invoice_id + RowNum - 1

select * 
from #Something

答案 1 :(得分:1)

在SQL Server中,您可以使用可更新的CTE:

with toudpate as (
      select t.*,
             row_number() over (partition by invoice_id order by invoice_date) -
 1 as seqnum
      from t
     )
update toupdate
    set invoice_id = invoice_id + seqnum
    where seqnum > 0;

在SQLite中,它看起来更像是:

update t
    set invoice_id = invoice_id + 1
    where exists (select 1
                  from t t2
                  where t2.invoice_id = t.invoice_id and t2.invoice_date < t.invoice_date
                 );

实际上,这也适用于SQL Server。

注意:这些都不能保证与另一张发票发生冲突。您应该修复该表,然后添加唯一约束/索引以防止将来出现重复:

create unique index unq_t_invoiceid on t(invoice_id);