Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 使用一对多联接更新语句_Mysql - Fatal编程技术网

Mysql 使用一对多联接更新语句

Mysql 使用一对多联接更新语句,mysql,Mysql,因此,我遇到了一个奇怪的情况,完全没有表现出我的预期 假设我有以下表格: DROP TABLE IF EXISTS test; CREATE TABLE test (somekey char(1) PRIMARY KEY, value1 int, value2 int); INSERT INTO test VALUES ("a", 1, 1), ("b", 2, 2), ("c", 3, 3); DROP TABLE IF EXISTS test2; CREATE TABLE test2

因此,我遇到了一个奇怪的情况,完全没有表现出我的预期

假设我有以下表格:

DROP TABLE IF EXISTS test;
CREATE TABLE test (somekey char(1) PRIMARY KEY, value1 int, value2 int);

INSERT INTO test VALUES 
("a", 1, 1),
("b", 2, 2),
("c", 3, 3);

DROP TABLE IF EXISTS test2;
CREATE TABLE test2 (somekey char(1), thing int, value int);

INSERT INTO test2 VALUES 
("a", 100, 10),
("a", 200, 10),
("b", 100, 20),
("b", 200, 20),
("c", 100, 30),
("c", 200, 30);
现在我想基于
test2
更新
test

UPDATE 
    test AS t 
    JOIN test2 AS t2 
        ON t.somekey = t2.somekey
SET
    t.value1 = IF(t2.thing = 100, t2.value, t.value1),
    t.value2 = IF(t2.thing = 200, t2.value, t.value2);
这是我的输出:

SELECT * FROM test;
+---------+--------+--------+
| somekey | value1 | value2 |
+---------+--------+--------+
| a       |     10 |      1 |
| b       |     20 |      2 |
| c       |     30 |      3 |
+---------+--------+--------+
由于某些原因,
value2
未更新

我发现,如果我改变test2,在100之前插入200,则情况正好相反。这让我相信MySQL本质上是按
somekey
分组的,完全忽略了
test2
中的一半行。但是,如果我执行完全相同的联接,并根据
test
更新
test2
中的某些内容,则它不会进行分组,并且
test2
中的所有六行都会更新

简单的解决方案是简单地连接到
test2
两次,如下所示:

UPDATE 
    test AS t 
    JOIN test2 AS t100 
        ON t100.somekey = t.somekey
        AND t100.thing = 100
    JOIN test2 AS t200
        ON t200.somekey = t.somekey
        AND t200.thing = 200
SET
    t.value1 = t100.value,
    t.value2 = t200.value;

但我觉得我不应该这样做。第一次更新有什么问题?为什么MySQL会这样

使用联接进行更新时,如果没有筛选器(其中),将有笛卡尔积。在这种情况下,由于每行
test
有两行
test2
,这意味着每行
test
将有两次更新

发件人:

每个匹配行更新一次,即使它多次匹配条件。对于多表语法,不能使用ORDER BY和LIMIT

据我所知,这意味着我们无法控制在更新期间使用2个可能的行值中的哪一个-MySql选择了
value=value
选项


您的第二个更新查询只为
test.value1
test.value2
定义了一个可能的值,从而消除了歧义。

Ah,感谢您在文档中找到这个值。至少这似乎是有意的行为。