Як оновити одну таблицю на основі значень іншої таблиці під час руху?


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.isoдорівнює він country.iso, чи рівний він, тоді додайте до цього запису country.coutryid. Я не міг придумати жодного способу це зробити. Чи маєте ви якесь уявлення, як це зробити?

Відповіді:


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

Використання MySQL оновлення синтаксису декількох таблиць:

14.2.11 ОНОВЛЕННЯ Синтаксис

Зауважте, що у ваших ізо-стовпцях є дві різні довжини та типи даних. Насправді є два окремих набори кодів ISO, 2-літерні та 3-літерні, тож ви насправді не зможете приєднатися до цих стовпців:

ISO 3166-1

Умова приєднання USING (iso)замість цього ON ips.iso = country.isoтеж працює.


Ви геній, на який відповідаєте, врятував мій час
Хамфрі

Мене дивує, як мало коду потрібно для виконання цієї дії!
Метт Кременс

32

Рішення @Cade Roux дає мені синтаксичну помилку, правильною для mysql 5.5.29 є:

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

без ключового слова "ВІД"


1
З тих пір це було виправлено, здається ...
rogerdpack


4

дякую @Cade, але я знайшов просте рішення для нього:

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

5
Існує різниця в поведінці моєї версії - ваша версія встановить її на NULL, якщо вона не знайдена, моя не змінить існуюче значення, якщо воно не буде відповідати. Це може бути або не бажано. Також план виконання може відрізнятися залежно від оптимізатора.
Кейд Ру

@CadeRoux Я не думав про NULL частину, дякую.
ALH

1
@ john.locke Це, мабуть, не проблема - коли ви додасте новий стовпець, я припускаю, що це буде NULL, а також іноземний ключ, тому недійсні записи все одно не дозволятимуться. Але важко сказати з того, що було прямо сказано у вашому запитанні.
Кейд Ру
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.