2015-06-17 2 views
0

Я знаю, что этот вопрос задавался несколько раз. Решение состоит в том, чтобы использовать вторую идентичную таблицу не напрямую, а как виртуальную таблицу с использованием SELECT. Я разработал два таких запроса с виртуальной таблицей. Один не работает (A), а другой (B) делает, и я не понимаю, почему (A) не работает.MySQL UPDATE with JOIN в той же таблице

У кого-нибудь есть объяснение?

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

В MYSQL он не поддерживает случай синтаксис. Лучше идти только на случай Б.

например: инструкция установки обновления не поддерживает вспомогательный запрос.

В SQL-сервере, oracle и т. Д. Он будет поддерживать синтаксис A и Case B.

Я думаю, что эта информация полезна для вас.

Спасибо ..

+0

Благодарим за информацию. Но не поддерживает ли версия (B) подзапрос? Я полагаю, вы имеете в виду, что подзапрос с той же таблицей не разрешен в SET-части. С другой таблицей это сработает. – giordano

Смежные вопросы