2009-04-30 6 views
145

У меня есть две таблицы и вы хотите обновлять поля в T1 для всех строк в LEFT JOIN.UPDATE несколько таблиц в MySQL с использованием LEFT JOIN

Для простого примера, обновить все строки следующего множества результатов:

SELECT T1.* FROM T1 LEFT JOIN T2 ON T1.id = T2.id WHERE T2.id IS NULL 

В MySQL manual говорится, что:

заявления UPDATE Multiple-таблицы могут использовать любой тип соединения допускается SELECT, например LEFT JOIN.

Но я не могу найти правильный синтаксис для этого в документированных таблицах UPDATE.

Каков правильный синтаксис?

ответ

267
UPDATE t1 
LEFT JOIN 
     t2 
ON  t2.id = t1.id 
SET  t1.col1 = newvalue 
WHERE t2.id IS NULL 

Обратите внимание, что для SELECT было бы более эффективно использовать NOT IN/NOT EXISTS синтаксис:

SELECT t1.* 
FROM t1 
WHERE t1.id NOT IN 
     (
     SELECT id 
     FROM t2 
     ) 

Смотрите статью в моем блоге подробности производительности:

К сожалению, MySQL не позволяет использовать целевую таблицу в подзапросе в операторе UPDATE, поэтому вам нужно придерживаться менее эффективного синтаксиса LEFT JOIN.

+0

Пробовал, что. Он дает синтаксическую ошибку около «где ...». –

+1

Несомненно. См. Обновление сообщения. – Quassnoi

+0

Он не работает в Oracle. В этом случае см. Эту статью [post] (http://stackoverflow.com/questions/2446764/oracle-update-statement-with-inner-join). –

23

То же самое можно применить к сценарию, в котором данные были нормализованы, но теперь вы хотите, чтобы таблица имела значения, найденные в третьей таблице. Следующее позволит вам обновить таблицу с информацией из третьей таблицы, которая понравится второй таблице.

UPDATE t1 
LEFT JOIN 
t2 
ON 
t2.some_id = t1.some_id 
LEFT JOIN 
t3 
ON 
t2.t3_id = t3.id 
SET 
t1.new_column = t3.column; 

Это было бы полезно в том случае, когда вы имели пользователей и групп, и вы хотите, чтобы пользователь сможет добавить свой собственный вариант названия группы, поэтому изначально вы хотели бы импортировать существующие имена групп в поле, где пользователь сможет его модифицировать.

4
Table A 
+--------+-----------+ 
| A-num | text  | 
| 1 |   | 
| 2 |   | 
| 3 |   | 
| 4 |   | 
| 5 |   | 
+--------+-----------+ 

Table B 
+------+------+--------------+ 
| B-num| date  | A-num | 
| 22 | 01.08.2003 |  2 | 
| 23 | 02.08.2003 |  2 | 
| 24 | 03.08.2003 |  1 | 
| 25 | 04.08.2003 |  4 | 
| 26 | 05.03.2003 |  4 | 

Я буду обновлять текст поля в таблице А с

UPDATE `Table A`,`Table B` 
SET `Table A`.`text`=concat_ws('',`Table A`.`text`,`Table B`.`B-num`," from           
",`Table B`.`date`,'/') 
WHERE `Table A`.`A-num` = `Table B`.`A-num` 

и прийти к этому результату:

Table A 
+--------+------------------------+ 
| A-num | text     | 
| 1 | 24 from 03 08 2003/| 
| 2 | 22 from 01 08 2003/|  
| 3 |      | 
| 4 | 25 from 04 08 2003/| 
| 5 |      | 
--------+-------------------------+ 

, где принимается только одно поле из таблицы B, но я приду к этому результату:

Table A 
+--------+--------------------------------------------+ 
| A-num | text          | 
| 1 | 24 from 03 08 2003      | 
| 2 | 22 from 01 08 2003/23 from 02 08 2003/|  
| 3 |           | 
| 4 | 25 from 04 08 2003/26 from 05 03 2003/| 
| 5 |           | 
+--------+--------------------------------------------+ 
0
UPDATE `Table A` a 
SET a.`text`=(
     SELECT group_concat(b.`B-num`,' from ',b.`date` SEPARATOR '/') 
     FROM `Table B` b WHERE (a.`A-num`=b.`A-num`) 
) 
+0

Возможно, это не сработает. –

-1
   DECLARE @cols VARCHAR(max),@colsUpd VARCHAR(max), @query VARCHAR(max),@queryUpd VARCHAR(max), @subQuery VARCHAR(max) 
DECLARE @TableNameTest NVARCHAR(150) 
SET @TableNameTest = @TableName+ '_Staging'; 
SELECT @colsUpd = STUF ((SELECT DISTINCT '], T1.[' + name,']=T2.['+name+'' FROM sys.columns 
       WHERE object_id = (
            SELECT top 1 object_id 
             FROM sys.objects 
            WHERE name = ''[email protected]+'' 
            ) 
       and name not in ('Action','Record_ID') 
       FOR XML PATH('') 
      ), 1, 2, '' 
     ) + ']' 


    Select @queryUpd ='Update T1 
SET '[email protected]+' 
FROM '[email protected]+' T1 
INNER JOIN '[email protected]+' T2 
ON T1.Record_ID = T2.Record_Id 
WHERE T2.[Action] = ''Modify''' 
EXEC (@queryUpd) 
+3

Пожалуйста, добавьте объяснение, чтобы сделать ответ более полезным! – namezero

+0

и отформатировать его должным образом –

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