Bagaimana cara memperbarui satu tabel berdasarkan nilai tabel lain saat itu juga?


40

Saya memiliki tabel atas nama ips seperti di bawah ini:

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

Mari kita asumsikan saya memiliki countryidbidang pada tabel ini dari tabel negara yaitu sebagai berikut:

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

Ada sekitar 100.000 catatan dalam tabel ips. Apakah ada permintaan untuk skenario berikut:
Periksa apakah ips.isosama dengan country.iso, jika sama maka tambahkan country.coutryid ke catatan itu. Saya tidak bisa memikirkan cara untuk melakukannya. Apakah Anda punya ide bagaimana melakukannya?

Jawaban:


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

Menggunakan MySQL perbarui beberapa tabel sintaks:

14.2.11 Sintaks Pembaruan

Perhatikan bahwa Anda memiliki dua panjang dan tipe data yang berbeda pada kolom iso Anda. Sebenarnya, ada dua set kode ISO yang terpisah, 2 huruf dan 3 huruf, sehingga Anda mungkin tidak dapat bergabung dengan kolom ini:

ISO 3166-1

Kondisi bergabung USING (iso)bukannya ON ips.iso = country.isoberfungsi juga.


Anda Genius yang Anda jawab menghemat waktu saya
humphrey

Ini mengherankan saya betapa sedikit kode yang diperlukan untuk melakukan tindakan ini!
Matt Cremeens

32

Solusi @Cade Roux memberi saya kesalahan sintaks, yang benar untuk mysql 5.5.29 adalah:

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

tanpa kata kunci "FROM".


1
Sejak itu telah diperbaiki, tampaknya ...
rogerdpack

10

Sintaks ini mungkin lebih baik dibaca

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

4

terima kasih @Cade, tapi saya menemukan solusi sederhana untuk itu:

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

5
Ada perbedaan perilaku pada versi saya - versi Anda akan mengaturnya menjadi NULL jika tidak ditemukan, milik saya tidak akan mengubah nilai yang ada jika tidak cocok. Ini mungkin atau mungkin tidak diinginkan. Juga rencana eksekusi dapat berbeda tergantung pada pengoptimal.
Cade Roux

@CadeRoux Saya tidak memikirkan bagian NULL, terima kasih.
ALH

1
@ john.locke Ini mungkin bukan masalah - ketika Anda menambahkan kolom baru, saya berasumsi itu NULL dan juga kunci asing, jadi entri yang tidak valid tidak akan diizinkan. Tetapi sulit untuk mengatakan dari apa yang secara eksplisit diberikan dalam pertanyaan Anda.
Cade Roux
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.