我知道有几次问这个问题。解决方案是使用第二个相同的表而不是直接使用SELECT作为虚拟表。我用虚拟表制作了两个这样的查询。一个不工作(A)而另一个(B)工作,我不明白为什么(A)不起作用。
有没有人对此有解释?
CREATE TABLE tab (
id INT
, valid_from DATE
, valid_to DATE
);
INSERT INTO TABLE tab (id,valid_from, valid_to)
VALUES
(1,'2000-01-01', NULL)
, (1,'2000-01-06', NULL)
, (1,'2000-01-20', NULL)
, (2,'2000-01-01', NULL)
, (2,'2000-01-10', NULL)
;
-- Case (A)
UPDATE tab a
SET a.valid_to = (SELECT MIN(b.valid_from) - INTERVAL 1 DAY AS valid_to
FROM (SELECT b1.it, b1.valid_from -- virtual table
FROM tab b1
) AS b
WHERE a.id = b.id
AND b.valid_from > a.valid_from
)
;
-- Output: "You can't specify target table 'a' for update in FROM clause
-- Case (B)
UPDATE tab a
INNER JOIN (SELECT b1.id
, b1.valid_from
, (SELECT MIN(b2.valid_from) - INTERVAL 1 DAY -- virtual table
FROM tab b2
WHERE b1.id = b2.id
AND b2.valid_from > b1.valid_from
) AS valid_to
FROM tab b1
) b
ON a.id = b.id
AND a.valid_from = b.valid_from
SET a.valid_to = b.valid_to
;
结果:
id valid_from valid_to 1 2000-01-01 2000-01-05 1 2000-01-06 2000-01-19 1 2000-01-20 \N 2 2000-01-01 2000-01-09 2 2000-01-10 \N
答案 0 :(得分:1)
在MYSQL中,它不支持案例A语法。最好只去B案例。
例如:update set statement不支持子查询。
在SQL server,oracle等中,它将支持案例A和案例B语法。
我认为这些信息对您有用。
谢谢..