Bir tabloyu anında başka bir tablonun değerlerine göre nasıl güncelleyebilirim?


40

Aşağıdaki gibi ips adına bir tablo var:

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

countryidBu tabloda, aşağıdaki gibi ülke tablosundan bir alanım olduğunu varsayalım :

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

İps tablosunda yaklaşık 100.000 kayıt var. Aşağıdaki senaryo için herhangi bir sorgu var mı: Eşit olup
olmadığını kontrol edin , eğer eşitse, o kayıt için country.coutryid ekleyin. Bunu yapmanın hiçbir yolu düşünemedim. Bunun nasıl yapılacağı hakkında bir fikrin var mı?ips.isocountry.iso

Yanıtlar:


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

MySQL güncelleme çoklu tablo sözdizimini kullanarak:

14.2.11 GÜNCELLEME Sözdizimi

Iso sütunlarınızda iki farklı uzunluk ve veri türünüz olduğunu unutmayın. Aslında, iki ayrı ISO kodu grubu, 2 harf ve 3 harf vardır, bu nedenle gerçekte bu sütunlara katılamayabilirsiniz:

ISO 3166-1

Bunun USING (iso)yerine birleştirme koşulu da ON ips.iso = country.isoişe yarıyor.


Cevap
humphrey

Bu işlemi gerçekleştirmek için ne kadar az kodun gerekli olduğu beni şaşırtıyor!
Matt Cremeens

32

@Cade Roux'un çözümü bana bir sözdizimi hatası veriyor, mysql 5.5.29 için doğru olanı şudur:

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

"FROM" anahtar sözcüğü olmadan.


1
O zamandan beri
tamir edildi

10

Bu sözdizimi daha iyi okunabilir olabilir

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

4

thanks @Cade, ama bunun için basit bir çözüm buldum:

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

5
Sürümümde davranışlarda bir fark var - sürümünüz bulunmazsa NULL olarak ayarlayacaktır, eşleşmediğinde benimki mevcut bir değeri değiştirmeyecektir. Bu arzu edilebilir veya olmayabilir. Ayrıca uygulama planı, optimize ediciye bağlı olarak değişebilir.
Cade Roux,

@CadeRoux NULL rolünü düşünmedim, teşekkürler.
ALH

1
@ john.locke Büyük olasılıkla bir sorun değil - yeni sütunu eklediğinizde, NULL ve aynı zamanda bir yabancı anahtar olacağını farz ediyorum, bu nedenle geçersiz girişlere izin verilmez. Ancak, sorunuzda açıkça verilenlerden bahsetmek zor.
Cade Roux,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.