繁体   English   中英

在没有主键的情况下更新SQL Server中的重复项

[英]Update Duplicates in SQL Server without a primary key

我需要一条更新语句来解决SQL Server 2000上表中重复项的某些问题。表结构如下所示。 该表中没有主键。 我需要一条SQL语句,该语句将在有重复的情况下通过将值加5直到没有更多重复来更新值。

DocNumber       SeQNumber
Doc001           900
Doc001           900
Doc001           900
Doc001           903
Doc001           904

所需结果

DocNumber       SeqNUmber
Doc001           900
Doc001           905
Doc001           910
Doc001           903
Doc001           904

这就是我尝试过的内容我的最新尝试如下所示。 在该示例中,我只是添加了计数器,但实际需要的是+5。

Declare @count as integer = (SELECT COUNT(*) AS DUPLICATES
FROM            dbo.RM10101
GROUP BY DocNumbr, SeqNumbr
HAVING        (COUNT(*) > 1))


Declare @counter as integer =1
While @Counter < @count
begin
With UpdateData  As
(
SELECT  DocNumbr,SeqNumbr,
ROW_NUMBER() OVER (ORDER BY [SeqNumbr] DESC) AS RN
FROM RM10101
)
UPDATE  RM10101 SET SeqNumbr = (select max(SeqNumbr) from RM10101 where docNumbr =          RM10101.DocNumbr and SeqNumbr=RM10101.SeqNumbr) + (@counter)
FROM RM10101
INNER JOIN UpdateData ON RM10101.DocNumbr = UpdateData.DocNumbr 
where rn =@counter   
SET @counter = @counter + 1
end
end

任何帮助将非常感激。
谢谢,鲍勃

;with tb1(id, seqNUm, docNum) as (
SELECT  ROW_NUMBER() OVER (ORDER BY SeQNumber), DocNumber, SeQNumber From table1
)

update tb1 set docnum=201 where id=2
  • 将ID设置为您要更新的任何行

这是一个开始,我很难将这个选择查询转换为更新语句。

--Build your tally table and sample data

if object_id('dbo.tally') is not null 
        drop table dbo.tally

select top 11000 
    identity(int,1,1) as n
into tally
from master.dbo.syscolumns sc1,
    master.dbo.syscolumns sc2

create table #test_table (
    DocNumber varchar(100),
    SeqNumber int
)

insert into #test_table
select 'Doc001', 900 union all
select 'Doc001', 900 union all
select 'Doc001', 900 union all
select 'Doc001', 903 union all
select 'Doc001', 904

select 
    t1.DocNumber,
    t1.SeqNumber,
    NewSeqNumber =  t1.SeqNumber + (5 * (t.n - 1))
from (
    select
        *,
        c = count(*)
    from #test_table
    group by
        DocNumber, SeqNumber
)t1
inner join tally t
    on t.n <= t1.c

drop table #test_table

不好的情况是

('Doc001',900),('Doc001',900),('Doc001',900),('Doc001',903),('Doc001',904),('Doc001',905),(' Doc001',905),('Doc001',905),('Doc001',910),('Doc001',910),('Doc001',915),('Doc001',915)

当您将行从900更新到905和910时,就会遇到以前不存在的重复情况。

要解决此问题,请使用以下查询:

WHILE EXISTS (SELECT * FROM Table1 GROUP BY DocNumber, SeqNumber HAVING count(*) > 1)
BEGIN

   With TableAdjusted as (
        select DocNumber, SeqNumber, row_number() over (partition by DocNumber, SeqNumber order by (select NULL)) RowID
        from Table1
   )

   update A
     set SeqNumber = (B.RowID - 1)*5 + B.SeqNumber
   from TableAdjusted A
   inner join TableAdjusted B
      on A.DocNumber = B.DocNumber and A.SeqNumber = B.SeqNumber and A.RowID = B.RowID 
   where A.RowID > 1
END

select * from Table1 order by DocNumber, SeqNumber

SQL小提琴

如果我有以下序列,脚本可能会失败:('Doc001',900),('Doc001',900),('Doc001',900),('Doc001',903),('Doc001',904) ,('Doc001',905),('Doc001',905),('Doc001',905),('Doc001',910),('Doc001',910),('Doc001',915),( 'Doc001',915)

该脚本将给出以下错误: 消息512,级别16,状态1,行1子查询返回了多个值。 当子查询遵循=,!=,<,<=,>,> =或将子查询用作表达式时,不允许这样做。

正确的脚本是:

WHILE (SELECT SUM(X.A) FROM (  SELECT COUNT(*) A FROM Table_1 GROUP BY DocNumber, SeqNumber HAVING count(*) > 1) X) > 0
BEGIN
   With TableAdjusted as (
        select DocNumber, SeqNumber, row_number() over (partition by DocNumber, SeqNumber order by (select NULL)) RowID
        from Table_1
   )

   update A
     set SeqNumber = (B.RowID - 1)*5 + B.SeqNumber
   from TableAdjusted A
   inner join TableAdjusted B
      on A.DocNumber = B.DocNumber and A.SeqNumber = B.SeqNumber and A.RowID = B.RowID 
   where A.RowID > 1
END

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM