【问题标题】:Removing rows when column has same value, and relating those rows to the same primary key in MySQL当列具有相同值时删除行,并将这些行与 MySQL 中的相同主键相关联
【发布时间】:2016-05-25 01:45:12
【问题描述】:

我正在使用 MySQL 5.7 处理电影数据库的项目。我有以下表格(不允许更改):

CREATE TABLE `movies` (
  `id` int NOT NULL AUTO_INCREMENT,
  `title` varchar(100) NOT NULL DEFAULT '',
  `director` varchar(100) NOT NULL DEFAULT '',
  PRIMARY KEY(`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE `genres` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(32) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE `genres_in_movies` (
  `genre_id` int NOT NULL,
  `movie_id` int NOT NULL,
  FOREIGN KEY (`genre_id`) REFERENCES `genres`(`id`),
  FOREIGN KEY (`movie_id`) REFERENCES `movies`(`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

我的记录必须更新以反映一些有效的genres。不幸的是,现在我有一堆重复的genres.name,即使genres.id 不同。我想做的是将所有等效的genres.name 合并为一个genres.idgenres.name。例如,如果我有这张桌子:

genres (old)
==================
id  |  name      |
==================
2   | Romance    |
------------------
6   | Romance    |
------------------
45  | Romance    |
==================

我只想得到一个条目,其中 genres.id = 2genres.name = 'Romance'

我可以通过以下查询轻松做到这一点:

DELETE FROM genres
WHERE genres.id NOT IN (SELECT * 
                       FROM (SELECT MIN(g.id)
                             FROM genres g
                             GROUP BY g.name) 
                       x);

但我也希望能够更新 genres_in_movies.genre_id 以反映 genres.id 更改,以便 movies 表不会损坏。那么如何更新genres_in_movies 表呢?

【问题讨论】:

    标签: mysql sql sql-update sql-delete


    【解决方案1】:

    第一次更新genres_in_movies

    update genres_in_movies gin join
           genres g
           on gin.genre_id = g.id join
           (select g2.name, min(g2.id) as minid
            from genres g2
            group by g2.name
           ) g2
           on g2.name = g.name and g2.minid <> g.id
        set gin.genre_id = g2.minid;
    

    然后进行删除。

    顺便说一句,您可以使用LEFT JOIN 改写DELETE

    DELETE g
        FROM genres g LEFT JOIN
             (SELECT MIN(g.id) as minid
              FROM genres g
              GROUP BY g.name
             ) gmin
             ON g.id = gmin.minid
        WHERE gmin.minid IS NULL;
    

    【讨论】:

    • 感谢您的快速回答。不幸的是,第一次更新不起作用。我得到ERROR: 1054, Unknown column 'g2.name' in 'on clause'
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-16
    • 1970-01-01
    • 2021-09-12
    • 1970-01-01
    • 2017-11-07
    • 2013-08-30
    相关资源
    最近更新 更多