我有两个MySQL表,我们可以调用Foo
和Bar
。
两个表都有一个名为PrizeGroupId
的列。目标是在这些列之间创建一对一的关系,并且我创建了存储过程来添加/编辑Foo
,通过Bar
中的一对一关系更新相应的行
问题在于数据并不总是以这种方式构建,我需要编写一个脚本来将数据从之前的状态(我将要描述)转换为一对一基于PrizeGroupId
的关系。
以前,Foo
中的多行可能具有相同的PrizeGroupId
,因此Bar
到Foo
中的条目之间存在一对多的关系PrizeGroupId
。我需要编写的脚本必须将这种性质的每个一对多实例分解为Foo
和Bar
之间的许多(几乎相同)一对一关系。
原则上,我想:
Foo
PrizeGroupId
中当前行的Foo
是否不唯一。 Bar
在PrizeGroupId
中添加一行。将所有旧行的其他数据复制到此新行中,使其“几乎相同”。Bar
删除旧的一对多行。我理解这个问题以及如何在编程语言中使用伪代码来实现这一点,但是我仍在学习MySQL并且不确定如何解决这种问题。
如果你可以通过MySQL代码和/或我可以采取/阅读的步骤来帮助我解决这个问题,那将是或者至少指向那种与此相关的阅读/ SO问题虽然我很难自己找到特定的资源,但是我会很难理解这个问题。
答案 0 :(得分:1)
你所要求的并不是那么难。你的一些想法正在阻碍。首先,几乎从不在SQL中进行迭代。 SQL不是那种语言。 SQL中的所有内容都是通过一系列内容完成的。
您的方法可以是:
要创建表,可以使用“create table foo2 like foo;”。非常有用。
要识别PrizeGroupId已经唯一的行,请使用以下内容:
jquery-rails
原始表格中剩余的行没有唯一的PrizeGroupId。更改PrizeGroupId值,使其唯一。
合并这两组以使用原始行重建表格,并使用PrizeGroupId唯一。
这很难的一个原因是因为如果您使用一对一连接创建了表,那么您将使用pk来连接表。 pk已经是独一无二的了,为什么要用别的东西呢。一旦你将表分开并且PrizeGroupId是唯一的,你可能想要考虑将fk的pk设置为bar的pk,然后删除PrizeGroupId列。
答案 1 :(得分:0)
对于Bar表,对于Foo中的每个记录都必须包含一个记录,而对于Foo中的PrizeGroupId字段,则要使其不存在。由于Foo.Id已经是唯一的,因此将其用作外键很有意义。
运行类似SELECT Foo.id, Bar.* FROM Foo INNER JOIN Bar USING (PrizeGroupId)
的查询将为我们提供Foo中每个记录的单个记录,以及Bar中对应记录的数据。因此,如果我们用此查询返回的内容替换Bar中的数据,然后将Foo.Id用作PrizeGroupId,我们将达到要求。
创建一个与Bar具有相同结构的临时表-类似于CREATE TABLE Bar_copy LIKE Bar
为Foo中的每个记录填充一个临时表,并将其与Bar中的相应记录连接起来-您需要列出Bar中的所有列,例如-INSERT INTO Bar_copy (id, field1, field2, field3) SELECT f.id, b.field1, b.field2, b.field3 FROM Foo AS f INNER JOIN Bar AS b USING (PrizeGroupId)
从Foo清除现有的PrizeGroupID字段-UPDATE Foo SET PrizeGroupId = NULL
清空现有的Bar表,并用临时表-INSERT INTO Bar (id, field1, field2, field3) SELECT id, field1, field2, field3 FROM Bar_copy
更新Foo中的外键值-UPDATE Foo SET PrizeGroupId = id
显然,请先备份!