Wie aktualisiere ich eine Tabelle basierend auf den Werten einer anderen Tabelle?


40

Ich habe eine Tabelle im Namen von ips wie folgt:

CREATE TABLE `ips` (
 `id` int(10) unsigned NOT NULL DEFAULT '0',
 `begin_ip_num` int(11) unsigned DEFAULT NULL,
 `end_ip_num` int(11) unsigned DEFAULT NULL,
 `iso` varchar(3) DEFAULT NULL,
 `country` varchar(150) DEFAULT NULL
) ENGINE=InnoDB

Nehmen wir an, ich habe countryidin dieser Tabelle ein Feld aus der nachstehenden Ländertabelle:

CREATE TABLE `country` (
 `countryid` tinyint(3) unsigned NOT NULL AUTO_INCREMENT,
 `name` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
 `ordering` smallint(5) unsigned NOT NULL DEFAULT '0',
 `iso` char(2) NOT NULL,
 PRIMARY KEY (`countryid`)
) ENGINE=InnoDB

Es gibt ungefähr 100.000 Datensätze in der IPS-Tabelle. Gibt es eine Abfrage für das folgende Szenario vor :
Überprüfen Sie, ob ips.isogleich country.iso, wenn es gleich ist dann zu diesem Eintrag country.coutryid hinzufügen. Ich konnte mir keine Möglichkeit vorstellen, das zu tun. Hast du eine Idee, wie das geht?

Antworten:


72
UPDATE ips INNER JOIN country
    ON ips.iso = country.iso
SET ips.countryid = country.countryid

Verwenden der MySQL-Syntax zum Aktualisieren mehrerer Tabellen:

14.2.11 UPDATE-Syntax

Beachten Sie, dass Ihre ISO-Spalten zwei verschiedene Längen und Datentypen haben. Tatsächlich gibt es zwei separate Sätze von ISO-Codes, 2-Buchstaben- und 3-Buchstaben-Codes, sodass Sie in Wirklichkeit möglicherweise nicht in der Lage sind, diese Spalten zu verbinden:

ISO 3166-1

Die Join - Bedingung USING (iso)statt ON ips.iso = country.isoArbeiten zu.


Sie sind ein Genie, das Sie antworten, sparte meine Zeit
humphrey

Es wundert mich, wie wenig Code erforderlich ist, um diese Aktion auszuführen!
Matt Cremeens

32

Die Lösung von @Cade Roux gibt mir einen Syntaxfehler, der richtige für mysql 5.5.29 ist:

UPDATE ips 
INNER JOIN country
    ON ips.iso = country.iso
SET ips.countryid = country.countryid

ohne das Schlüsselwort "FROM".


1
Es wurde seitdem behoben, scheint ...
Rogerdpack

10

Diese Syntax ist möglicherweise besser lesbar

UPDATE country p, ips pp
SET pp.countryid = p.countryid
WHERE pp.iso = p.iso

4

danke @Cade, aber ich habe eine einfache Lösung dafür gefunden:

update ips set countryid=(select countryid from country where ips.iso=country.iso )

5
Es gibt einen Unterschied im Verhalten zu meiner Version - Ihre Version setzt es auf NULL, wenn es nicht gefunden wird, meine ändert keinen vorhandenen Wert, wenn es nicht übereinstimmt. Dies kann wünschenswert sein oder auch nicht. Auch der Ausführungsplan kann je nach Optimierer unterschiedlich sein.
Cade Roux

@CadeRoux Ich habe nicht über NULL nachgedacht, danke.
ALH

1
@ john.locke Es ist wahrscheinlich kein Problem - wenn Sie die neue Spalte hinzufügen, gehe ich davon aus, dass sie NULL und auch einen Fremdschlüssel enthält, sodass ungültige Einträge sowieso nicht zulässig sind. Aber es ist schwer zu sagen, was in Ihrer Frage explizit angegeben wurde.
Cade Roux
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.