【问题标题】:MySQL UPDATE with JOIN on the same tableMySQL UPDATE 与 JOIN 在同一张表上
【发布时间】:2015-09-02 11:17:06
【问题描述】:

我知道这种问题已经被问过好几次了。解决方案是不直接使用第二个相同的表,而是使用 SELECT 作为 virtual 表。我用虚拟表计算了两个这样的查询。一个不起作用(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

【问题讨论】:

    标签: mysql join sql-update


    【解决方案1】:

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

    eg: update set 语句不支持子查询。

    在 SQL server、oracle 等中,它将支持 case A 和 Case B 语法。

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

    谢谢你..

    【讨论】:

    • 感谢您的信息。但是版本(B)是否也不包含子查询?我想你的意思是在 SET 部分中不允许使用同一个表的子查询。对于另一个表,这将起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-08
    • 1970-01-01
    • 1970-01-01
    • 2011-10-18
    • 1970-01-01
    • 2016-10-14
    • 2013-01-25
    相关资源
    最近更新 更多