¿Cómo actualizar una tabla en función de los valores de otra tabla sobre la marcha?


41

Tengo una tabla a nombre de ips como a continuación:

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

Supongamos que tengo un countryidcampo en esta tabla de la tabla del país que es el siguiente:

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

Hay alrededor de 100,000 registros en la tabla ips. ¿Hay alguna consulta para el siguiente escenario?
Compruebe si ips.isoes igual a country.iso, si es igual, luego agregue country.coutryid a ese registro. No se me ocurrió ninguna forma de hacerlo. ¿Tienes alguna idea de cómo hacer eso?

Respuestas:


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

Usando la sintaxis de múltiples tablas de actualización de MySQL:

14.2.11 Sintaxis de ACTUALIZACIÓN

Tenga en cuenta que tiene dos longitudes y tipos de datos diferentes en sus columnas iso. De hecho, hay dos conjuntos separados de códigos ISO, de 2 letras y de 3 letras, por lo que en realidad es posible que no pueda unir estas columnas:

ISO 3166-1

La condición de unión en USING (iso)lugar de ON ips.iso = country.isofunciona también.


Eres un genio, tu respuesta me ahorró tiempo
— humphrey

¡Me sorprende lo poco que se necesita código para realizar esta acción!
— Matt Cremeens

32

La solución de @Cade Roux me da un error de sintaxis, el correcto para mysql 5.5.29 es:

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

sin la palabra clave "DE".


1
Desde entonces se ha solucionado, parece ...
— rogerdpack

10

Esta sintaxis podría ser mejor legible

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

4

gracias @Cade, pero encontré una solución simple para ello:

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

55
Hay una diferencia en el comportamiento de mi versión: su versión la establecerá en NULL si no se encuentra, la mía no alterará un valor existente si no coincide. Esto puede o no ser deseable. Además, el plan de ejecución puede diferir según el optimizador.
— Cade Roux

@CadeRoux No pensé en la parte NULL, gracias.
— ALH

1
@ john.locke Probablemente no sea un problema: cuando agrega la nueva columna, supongo que será NULL y también una clave foránea, por lo que no se permitirán entradas no válidas de todos modos. Pero es difícil saber de lo que se ha dado explícitamente en su pregunta.
— Cade Roux
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.