【问题标题】:Update Duplicates in SQL Server without a primary key在没有主键的情况下更新 SQL Server 中的重复项
【发布时间】:2014-08-26 21:09:43
【问题描述】:

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

任何帮助将不胜感激。
谢谢, 鲍勃

【问题讨论】:

  • 好的,鲍勃。你已经尝试了什么?请与我们分享您的努力,即使他们没有成功。
  • 根据文档,ROW_NUMBER() 函数是在 SQL Server 2005 中添加的。您使用的是哪个版本的 SQL Server?
  • 感谢帕特里克的回复。抱歉,如果我在帖子中不清楚,但我需要根据 docnumbr 中的重复项更新 seqnumbr。
  • 它是 SQl 2000。我正在开发更高版本,不知道行号。

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


【解决方案1】:

如果我有如下序列,脚本可能会失败: ('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 行 子查询返回超过 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

【讨论】:

  • 感谢您评论我的脚本。我已经更新我的使用 EXISTS 而不是 COUNT 这将使查询更快。
【解决方案2】:
;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 任何你想更新的行

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

      一个糟糕的情况是

      ('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 Fiddle

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-10-26
        • 1970-01-01
        • 2010-12-21
        • 1970-01-01
        • 1970-01-01
        • 2019-12-22
        • 1970-01-01
        相关资源
        最近更新 更多