MySQL UPDATE与JOIN在同一个表上

时间:2015-06-17 09:41:21

标签: mysql join sql-update

我知道有几次问这个问题。解决方案是使用第二个相同的表而不是直接使用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

1 个答案:

答案 0 :(得分:1)

在MYSQL中,它不支持案例A语法。最好只去B案例。

例如:update set statement不支持子查询。

在SQL server,oracle等中,它将支持案例A和案例B语法。

我认为这些信息对您有用。

谢谢..