【问题标题】:Merging related data when a column should become unique当列应该变得唯一时合并相关数据
【发布时间】:2011-09-14 16:12:48
【问题描述】:

给定一个带有如下表的mysql数据库:

author:
+----+----------+
| id | name     |
+----+----------+
| 1  | John     |
| 2  | Peter    |
| 3  | Peter    |
+----+----------+

article:
+----+-----------+------+
| id | author_id | text |
+----+-----------+------+
| 1  | 2         | ...  |
| 2  | 3         | ...  |
| 3  | 3         | ...  |
+----+-----------+------+

作者表的名称列并非偶然设置为唯一的。现在我必须将相关文章“合并”到其中一位相关作者中,即将文章 2 和 3 的 author_id 设置为 2。我想在之后使 name-column 唯一。

我无法手动重新分配文章,因为受影响的记录太多。但我认为这个问题可能有现成的解决方案/sn-p。

【问题讨论】:

  • 问题不是很清楚,你能举个例子说明你想得到什么吗?
  • 我认为我不需要通过“将文章 2 和 3 的 author_id 设置为 2”来“编写”另一个 ASCII 表......
  • 你检查我的答案了吗?

标签: mysql sql merge one-to-many


【解决方案1】:

要更新您的 article 表,这将起到作用:

update article art
   set art.author_id = (select min(aut.id)
                          from author aut
                         where aut.name = (select a.name
                                             from author a
                                            where a.id = art.author_id));

select * from article;    
+ ------- + -------------- + --------- +
| id      | author_id      | text      |
+ ------- + -------------- + --------- +
| 1       | 2              |           |
| 2       | 2              |           |
| 3       | 2              |           |
+ ------- + -------------- + --------- +
3 rows

如果您更喜欢更紧凑的更新(并且更优化),那么您可以使用这个更新,它的工作方式相同:

update article art
   set art.author_id = (select min(aut.id)
                          from author aut
                         inner join author a on a.name = aut.name
                         where a.id = art.author_id);

最后,要删除多余的作者,你需要

delete a
  from author a
 inner join (
    select name, min(id) as min -- this subquery returns all repeated names and their smallest id
      from author
     group by name
    having count(*) > 1) repeated on repeated.name = a.name
 where a.id > repeated.min;     -- delete all repeateds except the first one

select * from author;    
+ ------- + --------- +
| id      | name      |
+ ------- + --------- +
| 1       | John      |
| 2       | Peter     |
+ ------- + --------- +
2 rows

这适用于任意数量的重复作者集。

希望对你有帮助

【讨论】:

    【解决方案2】:

    你可以先更新文章,使用同名的最低作者ID

    UPDATE art SET art.author_id =
        (SELECT MIN(a1.id) FROM author a1 WHERE a1.Name = a2.name
            FROM article art INNER JOIN author a2 ON art.author_id = a2.id)
    

    然后删除同名的上位作者

    PS。我没有测试过 SQL 但应该可以工作。

    【讨论】:

    • 我以前从未在单个选择查询中看到过两个“from”。我无法在没有更新的情况下运行选择查询。这是仅与“udpate”一起使用的特殊事物,还是错误?
    猜你喜欢
    • 1970-01-01
    • 2021-02-18
    • 1970-01-01
    • 2014-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-01
    • 1970-01-01
    相关资源
    最近更新 更多