首页 文章

使用LEFT JOIN在MySQL中更新多个表

提问于
浏览
150

我有两个表,并希望更新LEFT JOIN中所有行的T1中的字段 .

举个简单的例子,更新以下结果集的所有行:

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

MySQL manual指出:

多表UPDATE语句可以使用SELECT语句中允许的任何类型的连接,例如LEFT JOIN .

但是,在记录的多表UPDATE中,我无法找到正确的语法 .

什么是正确的语法?

5 回答

  • 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  |
    

    我将更新表A中的字段文本

    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   |                                            |
    +--------+--------------------------------------------+
    
  • -1
    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 语句的子查询中使用目标表,'s why you' ll需要坚持使用效率较低的 LEFT JOIN 语法 .

  • 0

    同样可以应用于数据已规范化的场景,但现在您希望表在第三个表中找到值 . 以下内容允许您使用第二个表所喜欢的第三个表中的信息更新表 .

    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;
    

    这对于您拥有用户和组的情况非常有用,并且您希望用户能够添加他们自己的组名变体,因此最初您希望将现有组名导入到用户所在的字段中能够修改它 .

  • 24
    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 = ''+@TableNameTest+''
                                        )
                    and name not in ('Action','Record_ID')
                    FOR XML PATH('')
                ), 1, 2, ''
            ) + ']'
    
    
      Select @queryUpd ='Update T1
    SET '+@colsUpd+'
    FROM '+@TableName+' T1
    INNER JOIN '+@TableNameTest+' T2
    ON T1.Record_ID = T2.Record_Id
    WHERE T2.[Action] = ''Modify'''
    EXEC (@queryUpd)
    
  • 278
    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`)
    )
    

相关问题