将一对多转换为一对一关系MySQL

时间:2015-06-02 17:41:16

标签: mysql one-to-many one-to-one

我有两个MySQL表,我们可以调用FooBar

两个表都有一个名为PrizeGroupId的列。目标是在这些列之间创建一对一的关系,并且我创建了存储过程来添加/编辑Foo,通过Bar中的一对一关系更新相应的行

问题在于数据并不总是以这种方式构建,我需要编写一个脚本来将数据从之前的状态(我将要描述)转换为一对一基于PrizeGroupId的关系。

以前,Foo中的多行可能具有相同的PrizeGroupId,因此BarFoo中的条目之间存在一对多的关系PrizeGroupId。我需要编写的脚本必须将这种性质的每个一对多实例分解为FooBar之间的许多(几乎相同)一对一关系。

原则上,我想:

  1. 遍历Foo
  2. 查看PrizeGroupId中当前行的Foo是否不唯一。
  3. 为其指定唯一值(可能是当前项主键)
  4. 使用新BarPrizeGroupId中添加一行。将所有旧行的其他数据复制到此新行中,使其“几乎相同”。
  5. 完成所有操作后,从Bar删除旧的一对多行。
  6. 我理解这个问题以及如何在编程语言中使用伪代码来实现这一点,但是我仍在学习MySQL并且不确定如何解决这种问题。

    如果你可以通过MySQL代码和/或我可以采取/阅读的步骤来帮助我解决这个问题,那将是或者至少指向那种与此相关的阅读/ SO问题虽然我很难自己找到特定的资源,但是我会很难理解这个问题。

2 个答案:

答案 0 :(得分:1)

你所要求的并不是那么难。你的一些想法正在阻碍。首先,几乎从不在SQL中进行迭代。 SQL不是那种语言。 SQL中的所有内容都是通过一系列内容完成的。

您的方法可以是:

  1. 确定PrizeGroupId已经唯一的行集,并将它们移动到表的新副本。
  2. 要创建表,可以使用“create table foo2 like foo;”。非常有用。

    要识别PrizeGroupId已经唯一的行,请使用以下内容:

    jquery-rails
    1. 原始表格中剩余的行没有唯一的PrizeGroupId。更改PrizeGroupId值,使其唯一。

    2. 合并这两组以使用原始行重建表格,并使用PrizeGroupId唯一。

    3. 这很难的一个原因是因为如果您使用一对一连接创建了表,那么您将使用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,我们将达到要求。

  1. 创建一个与Bar具有相同结构的临时表-类似于CREATE TABLE Bar_copy LIKE Bar

  2. 为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)

  3. 从Foo清除现有的PrizeGroupID字段-UPDATE Foo SET PrizeGroupId = NULL

  4. 清空现有的Bar表,并用临时表-INSERT INTO Bar (id, field1, field2, field3) SELECT id, field1, field2, field3 FROM Bar_copy

  5. 中的记录重新填充
  6. 更新Foo中的外键值-UPDATE Foo SET PrizeGroupId = id

显然,请先备份!