错误? “SELECT LEFT JOIN”匹配所有行,但“UPDATE LEFT JOIN”忽略了一些。里面的例子

时间:2013-07-23 10:41:05

标签: mysql sql-update left-join primary-key rows-affected

我想用一个UPDATE查询更新两个表。我使用简单的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'

更新后,表格如下所示:

test_continents:

key
EU
SA

test_agents:

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年,而且我不会问这样的问题,但我无法解释它,我需要帮助......

更新

我用INT(2)字段而不是CHAR(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%正确的。

有没有人解释???

提前致谢。

0 个答案:

没有答案