![](/img/trans.png)
[英]create primary key on existing table without primary key in 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
这是一个开始,我很难将这个选择查询转换为更新语句。
--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
如果我有以下序列,脚本可能会失败:('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.