我正在两个表之间进行数据迁移(拆分出一个相关的表)。现有表为reminders
,它具有一start
列和一个dateset_id
指向新dateset
表的新添加的列,该表也具有一start
列。对于每一行reminders
,我要INSERT
一个新的行dateset
与start
复制价值,并UPDATE
在相应的行reminders
与新插入的dateset
ID。
这是我尝试过的SQL:
WITH inserted_datesets AS (
INSERT INTO dateset (start)
SELECT start FROM reminder
RETURNING reminder.id AS reminder_id, id AS dateset_id
)
UPDATE reminder
SET dateset_id = ids.dateset_id
FROM inserted_datesets AS ids
WHERE reminder.id = ids.reminder_id
我收到一个错误missing FROM-clause entry for table "reminder"
,因为我reminder.id
在该RETURNING
子句中包括了该列,但实际上没有为插入选择它。这是有道理的,但我不知道如何修改查询以执行所需的操作。我缺少一种完全不同的方法吗?
有几种解决问题的方法。
1.临时添加一列
正如其他人提到的那样,简单的方法是将列临时添加reminder_id
到中dateset
。原装填充它IDs
从reminder
表。使用它reminder
与dateset
表连接。删除临时列。
2.何时启动是唯一的
如果该start
列的值是唯一的,则可以通过将reminder
table与该dateset
列上的表连接起来而无需额外的start
列。
INSERT INTO dateset (start)
SELECT start FROM reminder;
WITH
CTE_Joined
AS
(
SELECT
reminder.id AS reminder_id
,reminder.dateset_id AS old_dateset_id
,dateset.id AS new_dateset_id
FROM
reminder
INNER JOIN dateset ON dateset.start = reminder.start
)
UPDATE CTE_Joined
SET old_dateset_id = new_dateset_id
;
3.启动时不是唯一的
即使在这种情况下,也可以在没有临时列的情况下进行操作。主要思想如下。让我们看一下这个例子:
我们有两个reminder
具有相同start
值和ID 3和7的行:
reminder
id start dateset_id
3 2015-01-01 NULL
7 2015-01-01 NULL
将它们插入之后dateset
,将生成新的ID,例如1和2:
dateset
id start
1 2015-01-01
2 2015-01-01
我们如何链接这两行并不重要。最终结果可能是
reminder
id start dateset_id
3 2015-01-01 1
7 2015-01-01 2
或者
reminder
id start dateset_id
3 2015-01-01 2
7 2015-01-01 1
这两个变体都是正确的。这带给我们以下解决方案。
只需首先插入所有行。
INSERT INTO dateset (start)
SELECT start FROM reminder;
在start
知道列不是唯一的情况下匹配/联接列上的两个表。通过添加ROW_NUMBER
和连接两列来“使它变得唯一”
。可以使查询更短,但是我明确说明了每个步骤:
WITH
CTE_reminder_rn
AS
(
SELECT
id
,start
,dateset_id
,ROW_NUMBER() OVER (PARTITION BY start ORDER BY id) AS rn
FROM reminder
)
,CTE_dateset_rn
AS
(
SELECT
id
,start
,ROW_NUMBER() OVER (PARTITION BY start ORDER BY id) AS rn
FROM dateset
)
,CTE_Joined
AS
(
SELECT
CTE_reminder_rn.id AS reminder_id
,CTE_reminder_rn.dateset_id AS old_dateset_id
,CTE_dateset_rn.id AS new_dateset_id
FROM
CTE_reminder_rn
INNER JOIN CTE_dateset_rn ON
CTE_dateset_rn.start = CTE_reminder_rn.start AND
CTE_dateset_rn.rn = CTE_reminder_rn.rn
)
UPDATE CTE_Joined
SET old_dateset_id = new_dateset_id
;
我希望可以从代码中清楚地知道它的作用,尤其是当您将它与没有的简单版本进行比较时ROW_NUMBER
。显然,即使start
是唯一的,复杂的解决方案也可以使用,但效率却不如简单的解决方案。
此解决方案假定dateset
在此过程之前为空。
问题内容: 我有两个表,具有相同的架构- 我想将test2表中的值插入到test1中,但是如果具有相同主键的行已经存在,请对其进行更新。我知道在mysql中,您可以使用ON DUPLICATE KEY UPDATE做类似的事情- 但是我不知道如何使用另一个表中的SELECT来执行上述查询。我正在寻找的是表格查询- 该查询显然是无效的。如果有人可以从中提出有效的查询,我将不胜感激。 问题答案: 这应
null 目前我可以完成第1和第2步,但是(假设可以完成)我无法获得第3步中“not exist”的语法。 这是我当前的代码:
问题内容: 我是SQL的初学者,对Transact-SQL不太了解。 我意识到这是一个新手问题,但是我正在寻找一个简单的解决方案。 我有一个带有一些列()的表。 主表 我想从该表中选择数据并插入到其他两个表中。 第一桌 是来自的前三个字符的组合 第一个表中的数据按的前三个字符和客户代码分组 第二张桌子 那么,如何通过使用SQL选择主表的行来插入第一张表和第二张表呢? 感谢您的所有答复。 问题答案:
问题内容: 考虑以下两个表 表格1 表2 如何在表2没有表1的ID的情况下从表2将数据插入表1? 换句话说,我想要以下结果: 表2 问题答案: 在你的问题的措辞有点混乱,因为你首先要问 我如何将数据插入 表1 从表2中 但此时你显示了预期的结果 表2 。 现在,如果您想使用table2中不存在的s将table1中的行插入table2中,则可以使用这种方式 这是 SQLFiddle 演示 或者 这是
问题内容: 显然,以下是不正确的。 我得到的价值: SQL查询: MySQL说: 1093-您无法在FROM子句中指定目标表’aTable’用于更新 因此,我试图制作一个位图表,每一行对应一个位,并具有一个“ map”值。 要插入表中,我不想执行两个查询,而是想执行一个查询。我应该怎么做? 没有人对此发表评论,但是由于我正在尝试制作位图,因此应该是* 2而不是^ 2,是我的错误,请注意,这就是为什
问题内容: 我要寻找正确的语法和方式做直接从SQL如下:插入或更新(如果数据已经内部存在)从包含在数据与两者都具有相同的复合主键。 这两个表的定义为: 将定期删除并填充。 因为相同的定义,但将包含数据的更多的行和我需要的是从插入从未见过值入,并更新现有的行。 我曾经做过这种插入,但是我不知道如何处理更新和复合主键: 编辑:我正在使用 SQL Server 9.00.5000 编辑:另一种受MERG