Como atualizar uma tabela com base nos valores de outra tabela em tempo real?


40

Eu tenho uma tabela no nome de ips como abaixo:

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

Vamos supor que eu tenha um countryidcampo nesta tabela da tabela de países que é o seguinte:

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

Existem cerca de 100.000 registros na tabela ips. Existe alguma consulta para o seguinte cenário:
Verifique se ips.isoé igual a country.iso, se for igual, adicione country.coutryid a esse registro. Eu não conseguia pensar em nenhuma maneira de fazer isso. Você tem alguma ideia de como fazer isso?

Respostas:


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

Usando o MySQL atualize a sintaxe de várias tabelas:

14.2.11 Sintaxe UPDATE

Observe que você tem dois comprimentos e tipos de dados diferentes em suas colunas iso. De fato, existem dois conjuntos separados de códigos ISO, 2 e 3 letras, portanto, na verdade, talvez você não possa ingressar nessas colunas:

ISO 3166-1

A condição de junção em USING (iso)vez de ON ips.iso = country.isotambém funciona.


Você é um gênio você responder salvou o meu tempo
Humphrey

Surpreende-me quão pouco código é necessário para executar esta ação!
Matt Cremeens 24/06

32

A solução do @Cade Roux me dá um erro de sintaxe, o correto para o mysql 5.5.29 é:

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

sem a palavra-chave "FROM".


11
Desde então, foi corrigido, parece ...
rogerdpack 6/18

10

Essa sintaxe pode ser melhor legível

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

4

obrigado @Cade, mas encontrei uma solução simples para isso:

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

5
Há uma diferença de comportamento na minha versão - sua versão a definirá como NULL se não for encontrada, a minha não alterará um valor existente se não for correspondida. Isso pode ou não ser desejável. Além disso, o plano de execução pode diferir dependendo do otimizador.
Cade Roux

@CadeRoux Eu não pensei na parte NULL, obrigado.
ALH

11
@ john.locke Provavelmente não é um problema - quando você adiciona a nova coluna, suponho que seja NULL e também uma chave estrangeira, para que entradas inválidas não sejam permitidas. Mas é difícil distinguir do que foi explicitamente indicado na sua pergunta.
Cade Roux
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.