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

时间:2014-08-26 01:27:26

标签: sql sql-server sql-server-2000

我需要一个更新语句来解决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

非常感谢任何帮助 谢谢, 鲍勃

4 个答案:

答案 0 :(得分:0)

;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要更新的行

答案 1 :(得分:0)

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

--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

答案 2 :(得分:0)

不好的情况是

  

(&#39; Doc001&#39;,900),(&#39; Doc001&#39;,900),(&#39; Doc001&#39;,900),(&#39; Doc001&#39; ;,903),   (&#39; Doc001&#39;,904),(&#39; Doc001&#39;,905),(&#39; Doc001&#39;,905),(&#39; Doc001&#39;,905) )   (&#39; Doc001&#39;,910),(&#39; Doc001&#39;,910),(&#39; Doc001&#39;,915),(&#39; Doc001&#39;,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 Fiddle

答案 3 :(得分:0)

如果我的序列如下,脚本可能会失败: (&#39; Doc001&#39;,900),(&#39; Doc001&#39;,900),(&#39; Doc001&#39;,900),(&#39; Doc001&#39;,903 ),(&#39; Doc001&#39;,904),(&#39; Doc001&#39;,905),(&#39; Doc001&#39;,905),(&#39; Doc001&#39; ,905),(&#39; Doc001&#39;,910),(&#39; Doc001&#39;,910),(&#39; Doc001&#39;,915),(&#39; Doc001&# 39; 915)

该脚本将给出如下错误: Msg 512,Level 16,State 1,Line 1 子查询返回的值超过1。当子查询遵循=,!=,&lt;,&lt; =,&gt;,&gt; =或子查询用作表达式时,不允许这样做。

正确的脚本将是:

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