あるテーブルを別のテーブルの値に基づいてその場で更新する方法は?


40

私は次のように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.isocountry.iso、等しい場合は、そのレコードにcountry.coutryidを追加します。私はそれを行う方法を考えることができませんでした。それを行う方法はありますか?

回答:


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

MySQLを使用して、複数のテーブル構文を更新します。

14.2.11 UPDATE構文

iso列には2つの異なる長さとデータ型があることに注意してください。実際には、2文字と3文字の2つのISOコードセットがあり、実際にはこれらの列を結合できない場合があります。

ISO 3166-1

結合条件USING (iso)ON ips.iso = country.iso機能します。


あなたは答える天才であり、私の時間を節約しました
ハンフリー

このアクションを実行するのに必要なコードがどれほど少ないか、私には驚かされます!
マットクレームズ

32

@Cade Rouxのソリューションでは構文エラーが発生します。mysql5.5.29の正しいものは次のとおりです。

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

「FROM」キーワードなし。


1
それは修正されたようです
...-rogerdpack


4

@Cadeに感謝しますが、簡単な解決策を見つけました:

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

5
私のバージョンには動作に違いがあります-バージョンが見つからない場合はNULLに設定され、一致しない場合は既存の値が変更されません。これは望ましい場合と望ましくない場合があります。また、実行計画はオプティマイザーによって異なる場合があります。
ケイドRouxの

@CadeRoux NULL部分については考えませんでした、ありがとう。
ALH

1
@ john.lockeこれはおそらく問題ではありません。新しい列を追加すると、それはNULLであり外部キーでもあると想定しているため、無効なエントリは許可されません。しかし、あなたの質問で明示的に与えられたものから区別することは困難です。
ケイドRouxの
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.