首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将一对多转换为一对一关系MySQL

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

Stack Overflow用户
提问于 2015-06-02 17:41:15
回答 2查看 3.8K关注 0票数 0

我有两个MySQL表,我们可以称之为FooBar

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

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

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

原则上,我想:

  1. 迭代Foo
  2. 查看当前行的PrizeGroupIdFoo中是否是唯一的。
  3. 给它分配一个唯一的值(可能是当前项的主键)
  4. Bar中添加一行新的PrizeGroupId。将旧行的所有其他数据复制到这个新行中,使其“几乎相同”。
  5. 说到底,从Bar中删除旧的一对多行。

我理解这个问题,以及如何用一种编程语言用伪代码来解决这个问题,但是我仍然在学习MySQL,并且不知道如何解决这种性质的问题。

如果您可以通过MySQL代码向我提供帮助和/或我可以采取/阅读哪些步骤来着手解决这个问题,或者至少向我指出与这类问题相关的阅读/问题,尽管我自己很难找到特定的资源,但是与这类问题有关的问题是值得赞赏的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-06-02 17:59:13

你想要的没那么难。你的一些想法妨碍了你。首先,几乎从不在SQL中迭代。SQL不是那种语言。SQL中的一切都是通过一组东西来完成的。

你的方法可以是:

  1. 标识PrizeGroupId已经唯一的行集,并将它们移动到表的新副本中。

要创建一个表,可以使用"create foo2 (类似foo;)“。非常有用。

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

代码语言:javascript
复制
create table test_30602977 (id int primary key, other int);
insert into test_30602977 values (1, 1), (2, 2), (3, 2);
select other, count(*) as count from test_30602977 group by other having count = 1;
  1. 保留在原始表中的行没有唯一的PrizeGroupId。更改PrizeGroupId值,使它们是唯一的。
  2. 将这两个集合合并,用原始行和PrizeGroupId唯一来重构表。

这很难的一个原因是,如果您用一对一的连接创建了表,那么您就会使用pk来加入这些表。pk已经是独一无二的了,所以为什么要使用其他的东西呢?一旦将表分开并且PrizeGroupId是唯一的,您可能需要考虑将foo的pk设置为bar的pk,然后删除PrizeGroupId列。

票数 1
EN

Stack Overflow用户

发布于 2020-05-19 08:48:14

所需的是Bar表包含Foo中每个记录的单个记录,而Foo中的PrizeGroupId字段包含unqiue。由于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中加入相应的记录-您需要列出条形图中的所有列,例如- 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 - UPDATE Foo SET PrizeGroupId = NULL清除现有的UPDATE Foo SET PrizeGroupId = NULL字段
  4. 清空现有的Bar表,并使用临时表- INSERT INTO Bar (id, field1, field2, field3) SELECT id, field1, field2, field3 FROM Bar_copy中的记录填充它
  5. 更新Foo - UPDATE Foo SET PrizeGroupId = id中的外键值

显然,先做个后援!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30602977

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档