使用唯一的递增值更新表中的 int 列

Posted

技术标签:

【中文标题】使用唯一的递增值更新表中的 int 列【英文标题】:Update int column in table with unique incrementing values 【发布时间】:2012-11-29 15:44:46 【问题描述】:

我正在尝试用每行唯一的值填充其 InterfaceID (INT) 列中缺少值的任何行。

我正在尝试执行此查询:

UPDATE prices SET interfaceID = (SELECT ISNULL(MAX(interfaceID),0) + 1 FROM prices) 
       WHERE interfaceID IS null

我希望 (SELECT ISNULL(MAX(interfaceID),0) + 1 FROM prices) 将针对每一行进行评估,但它只执行一次,因此我所有受影响的行都获得相同的值而不是不同的值。

这可以在单个查询中完成吗?

【问题讨论】:

【参考方案1】:
declare @i int  = (SELECT ISNULL(MAX(interfaceID),0) + 1 FROM prices)


update prices
set interfaceID  = @i , @i = @i + 1
where interfaceID is null

应该做的工作

【讨论】:

也检查this,希望对某人有所帮助。 (SELECT ISNULL(MAX(interfaceID),0) + 1 FROM prices)周围加括号 我正在使用 CURSOR 执行一些需要 15 分钟才能处理 80000 条记录的任务。我只是用这种方式,现在这个任务只需要 4 秒。救了我。谢谢。 你为什么在SELECTSET 上都有+1?不应该只在其中一个上吗? 伙计,我正在使用 @i+1 进行 while 循环,然后是更新语句,直到没有剩余。我让它运行了一夜,它已经完成了大约 600,000 条记录运行它并在 1 分 40 秒内完成了 700,000 条记录【参考方案2】:
DECLARE @IncrementValue int
SET @IncrementValue = 0 
UPDATE Samples SET qty = @IncrementValue,@IncrementValue=@IncrementValue+1

【讨论】:

【参考方案3】:

简单的查询是,只需将变量设置为您想要的某个数字。 然后通过从该数字增加 1 来更新您需要的列。对于所有行,它将通过递增 1 来更新每个行 id

SET @a  = 50000835 ;  
UPDATE `civicrm_contact` SET external_identifier = @a:=@a+1 
WHERE external_identifier IS NULL;

【讨论】:

【参考方案4】:

对于 Postgres

ALTER TABLE table_name ADD field_name serial PRIMARY KEY

参考:https://www.tutorialspoint.com/postgresql/postgresql_using_autoincrement.htm

【讨论】:

【参考方案5】:

假设你有这个表的主键(你应该有),以及使用 CTE 或 WITH,也可以使用带有自连接的更新到同一个表:

UPDATE a
SET a.interfaceId = b.sequence
FROM prices a
INNER JOIN
(
   SELECT ROW_NUMBER() OVER ( ORDER BY b.priceId ) + ( SELECT MAX( interfaceId ) + 1 FROM prices ) AS sequence, b.priceId
   FROM prices b
   WHERE b.interfaceId IS NULL
) b ON b.priceId = a.priceId

我假设主键是 price-id。

派生表别名 b 用于通过 ROW_NUMBER() 函数与主键列一起生成序列。对于列 interface-id 为 NULL 的每一行,这将生成一个具有唯一序列值和主键值的行。

可以按其他顺序而不是主键对序列进行排序。

序列通过子查询被当前 MAX interface-id + 1 偏移。 MAX() 函数忽略 NULL 值。

WHERE 子句将更新限制为那些为 NULL 的行。

然后将派生表连接到同一个表,别名 a,连接到主键列,其中要更新的列设置为生成的序列。

【讨论】:

【参考方案6】:

在基于 oracle 的产品中,您可以使用以下语句:

update table set interfaceID=RowNum where condition;

【讨论】:

【参考方案7】:

试试这样的:

with toupdate as (
    select p.*,
           (coalesce(max(interfaceid) over (), 0) +
            row_number() over (order by (select NULL))
           ) as newInterfaceId
    from prices
   )
update p
    set interfaceId = newInterfaceId
    where interfaceId is NULL

这并不能完全使它们连续,但它确实分配了新的更高的 id。要使它们连续,请尝试以下操作:

with toupdate as (
    select p.*,
           (coalesce(max(interfaceid) over (), 0) +
            row_number() over (partition by interfaceId order by (select NULL))
           ) as newInterfaceId
    from prices
   )
update p
    set interfaceId = newInterfaceId
    where interfaceId is NULL

【讨论】:

【参考方案8】:

你可以试试:

DECLARE @counter int
SET @counter = 0
UPDATE [table]
SET [column] = @counter, @counter = @counter + 1```

【讨论】:

以上是关于使用唯一的递增值更新表中的 int 列的主要内容,如果未能解决你的问题,请参考以下文章

如果我们使用自动递增的标识列和PK,则违反3NF

如何将具有自动递增值的列添加到 mySql 数据库的表中?

DB2 根据另一列中的不同值更新具有递增数字的列

使用自动递增的 ID 作为值的一部分将条目插入到其表中

使用同一列中的值更新表中的唯一列

实体框架递增列值而不查询它之前