如何根据另一个表的值动态更新一个表?

Ali*_*eza 48 mysql update

我有一个名为 ips 的表,如下所示:

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
Run Code Online (Sandbox Code Playgroud)

假设我countryid在国家/地区表中的此表上有一个字段,如下所示:

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
Run Code Online (Sandbox Code Playgroud)

ips 表中大约有 100,000 条记录。是否有以下情况的查询:
检查是否ips.iso等于country.iso,如果等于,则将 country.coutryid 添加到该记录中。我想不出任何方法来做到这一点。你知道怎么做吗?

Cad*_*oux 85

UPDATE ips INNER JOIN country
    ON ips.iso = country.iso
SET ips.countryid = country.countryid
Run Code Online (Sandbox Code Playgroud)

使用 MySQL 更新多表语法:

14.2.11 更新语法

请注意,您的 iso 列有两种不同的长度和数据类型。事实上,有两组独立的 ISO 代码,2 个字母和 3 个字母,因此您实际上可能无法加入这些列:

ISO 3166-1

连接条件USING (iso)而不是也ON ips.iso = country.iso有效。


lin*_*ico 33

@Cade Roux 的解决方案给了我一个语法错误,mysql 5.5.29 的正确解决方案是:

UPDATE ips 
INNER JOIN country
    ON ips.iso = country.iso
SET ips.countryid = country.countryid
Run Code Online (Sandbox Code Playgroud)

没有“FROM”关键字。


小智 13

这种语法可能更好读

UPDATE country p, ips pp
SET pp.countryid = p.countryid
WHERE pp.iso = p.iso
Run Code Online (Sandbox Code Playgroud)


Ali*_*eza 5

谢谢@Cade,但我找到了一个简单的解决方案:

update ips set countryid=(select countryid from country where ips.iso=country.iso )
Run Code Online (Sandbox Code Playgroud)

  • 我的版本在行为上有所不同 - 如果找不到,您的版本会将其设置为 NULL,如果不匹配,我的版本不会更改现有值。这可能是也可能不是可取的。此外,执行计划可能因优化器而异。 (5认同)