Jak na bieżąco aktualizować jedną tabelę na podstawie wartości innej tabeli?


40

Mam tabelę na imię ips, jak poniżej:

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

Załóżmy, że mam countryidpole na tej tabeli z tabeli kraju, która jest jak poniżej:

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

Tabela IPS zawiera około 100 000 rekordów. Czy istnieje zapytanie dotyczące następującego scenariusza:
Sprawdź, czy ips.isojest równe country.iso, czy jest równe, a następnie dodaj country.coutryid do tego rekordu. Nie mogłem wymyślić żadnego sposobu, aby to zrobić. Czy masz jakiś pomysł, jak to zrobić?

Odpowiedzi:


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

Za pomocą MySQL zaktualizuj składnię wielu tabel:

14.2.11 Składnia aktualizacji

Pamiętaj, że masz dwie różne długości i typy danych w kolumnach ISO. W rzeczywistości istnieją dwa oddzielne zestawy kodów ISO, 2-literowe i 3-literowe, więc w rzeczywistości możesz nie być w stanie dołączyć do tych kolumn:

ISO 3166-1

Warunek łączenia USING (iso)zamiast ON ips.iso = country.isodziała również.


Jesteś geniuszem, na który odpowiadasz, oszczędzając mi czas
humphrey

Dziwi mnie, jak mało kodu jest potrzebne do wykonania tej akcji!
Matt Cremeens

32

Rozwiązanie @Cade Roux daje mi błąd składniowy, poprawny dla mysql 5.5.29 to:

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

bez słowa kluczowego „FROM”.


1
Od tego czasu został naprawiony, wydaje się ...
rogerdpack

10

Ta składnia może być lepiej czytelna

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

4

dzięki @Cade, ale znalazłem proste rozwiązanie:

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

5
Istnieje różnica w zachowaniu mojej wersji - twoja wersja ustawi ją na NULL, jeśli nie zostanie znaleziona, moja nie zmieni istniejącej wartości, jeśli nie zostanie dopasowana. To może, ale nie musi być pożądane. Również plan wykonania może się różnić w zależności od optymalizatora.
Cade Roux,

@CadeRoux Nie pomyślałem o części NULL, dzięki.
ALH

1
@ john.locke Prawdopodobnie nie stanowi to problemu - po dodaniu nowej kolumny zakładam, że będzie to NULL, a także klucz obcy, więc nieprawidłowe wpisy i tak nie będą dozwolone. Trudno jednak odróżnić od tego, co zostało wyraźnie podane w twoim pytaniu.
Cade Roux,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.