SQL SELECT INSERT INTO 生成唯一 ID

Posted

技术标签:

【中文标题】SQL SELECT INSERT INTO 生成唯一 ID【英文标题】:SQL SELECT INSERT INTO Generate Unique Id 【发布时间】:2012-06-20 18:03:21 【问题描述】:

我正在尝试选择一个数据表并将此数据插入到另一个具有相似列名的文件中(它本质上是重复数据)。当前语法如下:

INSERT INTO TABLE1 (id, id2, col1, col2)
SELECT similiarId, similiarId2, similiarCol1, similiarCol2  
FROM TABLE2

我遇到的问题是为新插入的记录生成唯一的关键字段(声明为整数)。我不能使用 table2 的键,因为 table1 有现有数据,并且重复键值会出错。

我无法更改表架构,这些是自定义 id 列,不是由 DB 自动生成的。

【问题讨论】:

保留键的原始值重要吗? 不要从 table2 插入相似 ID,让 table table1 为行生成新 id table1 中的 ID 是自定义 ID 吗?如果没有,您可以在 ID 上使用 IDENTITY,它会自动为您创建 ID。 你可以对table1使用自动增量,不要像rs说的那样在table1中插入similarId。 你不能只在table1中添加一个标识列并将新列作为主键吗?然后,您只需在没有新主键列的情况下进行插入,身份就会自动生成您的键。 【参考方案1】:

table1 的 id 字段是否有自动增量?如果是这样,您能否从插入中丢失 similiarId 并让自动增量处理唯一键?

INSERT INTO TABLE1 (id2, col1, col2) SELECT similiarId2, similiarCol1, similiarCol2
FROM TABLE2

【讨论】:

这是一个自定义 id,不是由数据库自动递增/生成的。【参考方案2】:

根据您的要求,您需要像这样查询:

INSERT INTO TABLE1 (id, id2, col1, col2)
SELECT (ROW_NUMBER( ) OVER ( ORDER BY ID ASC )) 
+ (SELECT MAX(id) FROM TABLE1) AS similiarId
, similiarId2, similiarCol1, similiarCol2  
FROM TABLE2

我在这里做了什么: 添加了ROW_NUMBER(),它将从1开始,因此还添加了目标表ID的MAX()函数。

为了更好的解释See this SQLFiddle.

【讨论】:

【参考方案3】:

我不确定我是否理解正确: 您想从 TABLE2 复制所有数据,但要确保 TABLE2.similiarId 不在 TABLE1.id 中,也许这是您问题的解决方案:

DECLARE @idmax INT
SELECT @idmax = MAX(id) FROM TABLE1

INSERT INTO TABLE1 (id, id2, col1, col2)
SELECT similiarId + @idmax, similiarId2, similiarCol1, similiarCol2  
FROM TABLE2

现在插入不会因为主键违规而失败,因为每个插入的 id 都会大于 id 女巫已经在那里。

【讨论】:

+1。我建议这样做,只要它不是在大表上经常完成(性能问题 w/max),并且可以更改 similiarID “key”(没有参考问题)。否则,他们可能需要roll their own sequence 或使用带有身份的临时表。【参考方案4】:

如果 id 字段被定义为 auto-id 并且您将其排除在插入语句之外,那么 sql 将从可用池中生成唯一 id。

【讨论】:

这不是自动 ID 字段。【参考方案5】:

在 SQL Server 中,我们有函数 ROW_NUMBER,如果我对您的理解正确,以下代码将满足您的需求:

    INSERT INTO TABLE1 (id, id2, col1, col2)
    SELECT (ROW_NUMBER( ) OVER ( ORDER BY similiarId2 ASC )) + 6 AS similiarId, 
similiarId2, similiarCol1, similiarCol2  
    FROM TABLE2

ROW_NUMBER 将带来每行的编号,您可以为其添加一个“神奇值”,以使这些值与 TABLE1 的当前最大 ID 不同。假设您当前的最大 ID 为 6,那么将 ROW_NUMBER 的每个结果加 6 将得到 7、8、9 等。这样一来,TABLE1 的主键值就不会相同了。

我问了谷歌,它告诉我 Sybase 也有 ROW_NUMBER 功能(http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.help.sqlanywhere.12.0.1/dbusage/ug-olap-s-51258147.html),所以我想你可以试试。

【讨论】:

小心这个......他们没有指定他们正在使用 Sybase SQLAnywhere,他们只说'Sybase',所以他们很有可能指的是 Sybase ASE,据我所知没有ROW_NUMBER 功能? @sybkar,感谢您的评论。在这种情况下,我推荐 Jarek Bielicki 指出的方法,或者如果 user1464435 想要保证其连续的新 id,则使用带有标识列的临时表作为中间表。【参考方案6】:

如果你想制作一个相同的表,为什么不简单地使用(又快又脏)Select INTO 方法?

SELECT * INTO TABLE2
FROM TABLE1 

希望这会有所帮助。

【讨论】:

【参考方案7】:

如果 table1 不是自定义 ID,则将其设为 IDENTITY。

在table1中创建新的主键并将其设为IDENTITY,可以保持之前的ID格式相同(但不能保持主键)。

【讨论】:

更新数据库架构不是这里的选项,需要一个函数或 sql 查询来执行此操作,因为它是一个自定义 ID。【参考方案8】:

您最好的选择可能是在 Table2 上为 Table1.Id 添加一个额外的列。这样您就可以保留两组密钥。

(如果您正忙于数据合并,保留 Table1.Id 对于可能仍引用 Table1.Id 的任何外键可能很重要 - 然后您需要“修复”引用 Table1.Id 的表中的外键,现在需要引用表 2 中的适用键)。

【讨论】:

更新数据库架构不是这里的选项,需要一个函数或 sql 查询来执行此操作,因为它是一个自定义 ID。【参考方案9】:

如果您需要第二张桌子保持与第一张桌子相似的值,那么不要在第二张桌子上应用auto increment

【讨论】:

【参考方案10】:

如果您有大范围,并且想要轻松快速制作并且不关心 ID:

CONCAT 示例

INSERT INTO session(SELECT CONCAT("3000", id) as id, cookieid FROM `session2`)

但你也可以使用 REPLACE

【讨论】:

以上是关于SQL SELECT INSERT INTO 生成唯一 ID的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 中SELECT INTO 和 INSERT INTO SELECT 两种表复制语句

SQL insert into select 语句

使用 select 语句编写 Sql insert into 语句

[22]SQL INSERT INTO SELECT 语句

Oracle中insert into select和select into的区别

如何将 SQL INSERT INTO SELECT 与 codeigniter 一起使用