2016-05-25 5 views
0

Ich arbeite an einem Projekt mit MySQL 5.7, das sich um eine Filmdatenbank kümmert. Ich habe die folgenden Tabellen (die ich nicht ändern bin erlaubt):Zeilen entfernen, wenn Spalte denselben Wert hat, und diese Zeilen mit demselben Primärschlüssel in MySQL in Beziehung setzen

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; 

ich Aufzeichnungen hatte, die aktualisiert werden mussten einige gültige genres widerzuspiegeln. Leider habe ich nun eine Reihe von Duplikaten genres.name, obwohl sich die genres.id unterscheidet. Was ich tun möchte, ist die Konsolidierung aller gleichwertigen genres.name in eine einzige genres.id und genres.name. wenn ich diese Tabelle habe zum Beispiel:

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

Ich möchte nur mit einem einzigen Eintrag landen, wo genres.id = 2 und genres.name = 'Romance'.

Ich tue dies mit der folgenden Abfrage könnte leicht:

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

aber ich möchte auch in der Lage sein genres_in_movies.genre_id zu aktualisieren, um die genres.id Änderung widerzuspiegeln, so dass die movies Tabelle nicht bricht. Wie kann ich die Tabelle genres_in_movies aktualisieren?

Antwort

1

Erstes Update 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; 

tun dann die ENTF.

BTW, können Sie die DELETE mit LEFT JOIN umformulieren:

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; 
+0

Danke für die schnelle Antwort. Leider funktioniert das erste Update nicht. Ich bekomme 'ERROR: 1054, Unbekannte Spalte 'g2.name' in 'on clause'' – Alex