我有一个以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


让我们假设我在这张来自国家/地区表的表格上具有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


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

#1 楼

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


使用MySQL更新多表语法:

14.2.11 UPDATE语法

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

ISO 3166-1

加入条件USING (iso)而不是ON ips.iso = country.iso也是有效的。

评论


你是一个天才,你的回答节省了我的时间

–汉弗莱
18年1月7日在9:18

令我惊讶的是执行此操作所需的代码很少!

– Matt Cremeens
19年6月24日在13:31

你节省了我的时间。这也很好

–saber tabatabaee yazdi
20年7月22日在9:42

#2 楼

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

评论


此后已修复,似乎...

–rogerdpack
18-10-6在5:52

#3 楼

此语法可能更易读

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


#4 楼

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

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


评论


我的版本在行为上有差异-如果找不到,您的版本会将其设置为NULL,如果不匹配,则我的版本不会更改现有值。这可能是理想的,也可能不是理想的。执行计划也可能会因优化程序而异。

–Cade Roux
2012年7月19日在13:28



@CadeRoux我没考虑过NULL部分,谢谢。

– ALH
2012年7月19日下午13:32

@ john.locke可能不是问题-当您添加新列时,我假设它将为NULL以及外键,因此无论如何都将不允许输入无效。但是,很难从您的问题中明确给出的内容中分辨出来。

–Cade Roux
2012年7月19日在13:34