1 つの UPDATE クエリで 2 つのテーブルを更新したいと考えています。そのために単純な LEFT JOIN を使用します。不思議なことに、一致するすべての行が変更されるわけではありません。これはテーブルの例です:
DROP TABLE IF EXISTS `test_continents`, `test_agents`;
CREATE TABLE IF NOT EXISTS `test_continents` (
`key` char(2) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`key`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=FIXED;
INSERT INTO `test_continents` (`key`) VALUES('EU');
INSERT INTO `test_continents` (`key`) VALUES('NA');
CREATE TABLE IF NOT EXISTS `test_agents` (
`name` char(64) COLLATE utf8_unicode_ci NOT NULL,
`continent` char(2) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
PRIMARY KEY (`name`),
KEY `continent` (`continent`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=FIXED;
INSERT INTO `test_agents` (`name`, `continent`) VALUES('006', 'EU');
INSERT INTO `test_agents` (`name`, `continent`) VALUES('007', 'EU');
INSERT INTO `test_agents` (`name`, `continent`) VALUES('008', 'NA');
INSERT INTO `test_agents` (`name`, `continent`) VALUES('009', 'NA');
OPTIMIZE TABLE `test_continents`, `test_agents`;
これはサンプルの SELECT クエリで、すべての行に一致します。
SELECT
`test_agents`.`continent`,
`test_agents`.`name`
FROM `test_continents`
LEFT JOIN `test_agents` ON (
`test_agents`.`continent` = `test_continents`.`key`
)
WHERE
`test_continents`.`key` = 'NA'
これは UPDATE クエリです。
UPDATE `test_continents`
LEFT JOIN `test_agents` ON (
`test_agents`.`continent` = `test_continents`.`key`
)
SET
`test_continents`.`key` = 'SA',
`test_agents`.`continent` = `test_continents`.`key`
WHERE
`test_continents`.`key` = 'NA'
更新後、テーブルは次のようになります。
テスト大陸:
key
EU
SA
テストエージェント:
name continent
006 EU
007 EU
008 SA
009 NA
更新後、test_agent 009 の大陸フィールドがまだ「NA」のままである理由を誰か説明できますか?
INT フィールドを使用する場合、これは発生しないようですが、CHAR(2) フィールドが必要なので、テーブル構造については議論しないでください。これはバグ、機能、またはその他のものであるとだけ言ってください。
私はUbuntu 12.04とMySQL 5.5.29-1〜dotdeb.0を使用しています。私は15年以上コーダーであり、通常はそのようなお粗末な質問はしませんが、説明することはできず、助けが必要です...
アップデート:
CHAR(2) の代わりに INT(2) フィールドを使用して 2 番目の例を作成しました。この場合、UPDATE はすべての行に一致します。
CREATE TABLE IF NOT EXISTS `test_agents` (
`name` char(64) COLLATE utf8_unicode_ci NOT NULL,
`continent` int(2) NOT NULL DEFAULT '0',
PRIMARY KEY (`name`),
KEY `continent` (`continent`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=FIXED;
INSERT INTO `test_agents` (`name`, `continent`) VALUES('006', 1);
INSERT INTO `test_agents` (`name`, `continent`) VALUES('007', 1);
INSERT INTO `test_agents` (`name`, `continent`) VALUES('008', 2);
INSERT INTO `test_agents` (`name`, `continent`) VALUES('009', 2);
CREATE TABLE IF NOT EXISTS `test_continents` (
`key` int(2) NOT NULL,
PRIMARY KEY (`key`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=FIXED;
INSERT INTO `test_continents` (`key`) VALUES(1);
INSERT INTO `test_continents` (`key`) VALUES(2);
--
SELECT
`test_agents`.`continent`,
`test_agents`.`name`
FROM `test_continents`
LEFT JOIN `test_agents` ON (
`test_agents`.`continent` = `test_continents`.`key`
)
WHERE
`test_continents`.`key` = 2
--
UPDATE `test_continents`
LEFT JOIN `test_agents` ON (
`test_agents`.`continent` = `test_continents`.`key`
)
SET
`test_continents`.`key` = 3,
`test_agents`.`continent` = `test_continents`.`key`
WHERE
`test_continents`.`key` = 2
更新後の test_agents:
name continent
006 1
007 1
008 3
009 3
--
これが正常な動作だとは信じられません。両方の例の唯一の違いはフィールド タイプであるため、同じ行に影響するかどうか? クエリは 100% 正しいと確信しています。
誰か説明がありますか?
前もって感謝します。