【问题标题】:INNER JOIN in UPDATE sql for DB2DB2 的 UPDATE sql 中的 INNER JOIN
【发布时间】:2010-11-15 12:15:28
【问题描述】:

有没有办法在 DB2 的更新语句中使用连接?

Google 在这方面真的让我失望了

这大致就是我想要实现的目标(......除了明显工作......)

update file1 inner join file2                                 
       on substr(file1.firstfield,10,20) = substr(file2.anotherfield,1,10)                                                                    
set file1.firstfield = ( 'BIT OF TEXT' concat file2.something )                                                                             
where file1.firstfield like 'BLAH%'                             

干杯

【问题讨论】:

    标签: sql db2


    【解决方案1】:

    只更新符合条件的行,避免更新其他行中的空值:

    update table_one set field_1 = 'ACTIVE' where exists 
    (select 1 from table_two where table_one.customer = table_two.customer);
    

    它适用于 DB2/AIX64 9.7.8

    【讨论】:

    • 谢谢!你解决了我的问题。 (DB2 v11.1.4.4) update [schema].TableA set Column1 = 'Foo', Column2 = 'Bar' where exists ( select 1 from [schema].TableB where [schema].TableB.CommonColumn=[schema]. TableA.CommonColumn 和 [schema].TableB.key = 'condition' );我以前没有使用过这种语法,但奇怪的是它比连接好得多。
    【解决方案2】:

    你问

    update file1 f1
    set file1.firstfield=
    (
    select 'BIT OF TEXT' || f2.something
    from file2 f2
    where substr(f1.firstfield,10,20) = substr(f2.anotherfield,1,10)
    )
    where exists
    (
    select * from file2 f2
    where substr(f1.firstfield,10,20) = substr(f2.anotherfield,1,10)
    )
    and f1.firstfield like 'BLAH%'
    

    如果加入给出多个结果,你可以像这样强制更新

    update file1 f1
    set file1.firstfield=
    (
    select 'BIT OF TEXT' || f2.something
    from file2 f2
    where substr(f1.firstfield,10,20) = substr(f2.anotherfield,1,10)
    fetch first rows only
    )
    where exists
    (
    select * from file2 f2
    where substr(f1.firstfield,10,20) = substr(f2.anotherfield,1,10)
    )
    and f1.firstfield like 'BLAH%' 
    

    模板方法

    update table1 f1
    set (f1.field1, f1.field2, f1.field3, f1.field4)=
    (
    select f2.field1, f2.field2, f2.field3, 'CONSTVALUE'
    from table2 f2
    where (f1.key1, f1.key2)=(f2.key1, f2.key2) 
    )
    where exists 
    (
    select * from table2 f2
    where (f1.key1, f1.key2)=(f2.key1, f2.key2)
    ) 
    

    【讨论】:

      【解决方案3】:

      更新答案https://stackoverflow.com/a/4184237/565525

      如果您想要多列,可以这样实现:

      update file1
      set
        (firstfield, secondfield) = (
              select 'stuff' concat 'something from file2', 
                     'some secondfield value' 
              from file2
              where substr(file1.field1, 10, 20) = substr(file2.xxx,1,10) )
      where
        file1.foo like 'BLAH%'
      

      来源:http://www.dbforums.com/db2/1615011-sql-update-using-join-subquery.html#post6257307

      【讨论】:

        【解决方案4】:

        这是我刚刚开始工作的一个很好的例子:

        update cac c
        set ga_meth_id = (
            select cim.ga_meth_id 
            from cci ci, ccim cim 
            where ci.cus_id_key_n = cim.cus_id_key_n
            and ci.cus_set_c = cim.cus_set_c
            and ci.cus_set_c = c.cus_set_c
            and ci.cps_key_n = c.cps_key_n
        )
        where exists (
            select 1  
            from cci ci2, ccim cim2 
            where ci2.cus_id_key_n = cim2.cus_id_key_n
            and ci2.cus_set_c = cim2.cus_set_c
            and ci2.cus_set_c = c.cus_set_c
            and ci2.cps_key_n = c.cps_key_n
        )
        

        【讨论】:

          【解决方案5】:

          你没有说你的目标是什么平台。但是,将表称为文件让我相信您没有在 Linux、UNIX 或 Windows (LUW) 上运行 DB2。

          但是,如果您在 DB2 LUW 上,请参阅MERGE 语句:

          对于您的示例语句,这将被写为:

          merge into file1 a
             using (select anotherfield, something from file2) b
             on substr(a.firstfield,10,20) = substr(b.anotherfield,1,10)
          when matched and a.firstfield like 'BLAH%'
             then update set a.firstfield = 'BIT OF TEXT' || b.something;
          

          请注意:对于 DB2,SUBSTR 函数的第三个参数是要返回的字节数,而不是结束位置。因此,SUBSTR(a.firstfield,10,20) 返回 CHAR(20)。但是,SUBSTR(b.anotherfield,1,10) 返回 CHAR(10)。我不确定这是否是故意的,但这可能会影响您的比较。

          【讨论】:

          • “file”的使用很有趣,在使用 IBM i 的开发人员中,它通常与“table”互换使用。在这个 OS 中,DB2 表是一个外部描述的物理数据库文件。但是,可执行程序对象不是文件。
          【解决方案6】:

          试试这个然后告诉我结果:

          UPDATE File1 AS B                          
          SET    b.campo1 = (SELECT DISTINCT A.campo1
                             FROM  File2 A           
                             INNER JOIN File1      
                             ON A.campo2 = File1.campo2 
                             AND A.campo2 = B.campo2) 
          

          【讨论】:

          • 我不知道你是否注意到,但 OP 最后一次见到她是 2011 年 1 月 24 日 13:03。他/她不太可能回来。
          • @Linger 是的,但多年后搜索者仍能找到答案。如果一个答案是有效的,它总是相关的。
          【解决方案7】:

          update 语句中的连接是非标准的,并非所有供应商都支持。您尝试做的事情可以通过子选择来完成:

          update
            file1
          set
            firstfield = (select 'stuff' concat something from file2 where substr(file1.field1, 10, 20) = substr(file2.xxx,1,10) )
          where
            file1.foo like 'BLAH%'
          

          【讨论】:

            【解决方案8】:

            在标准 SQL 中,这种类型的更新如下所示:

            update a
               set a.firstfield ='BIT OF TEXT' + b.something
              from file1 a
              join file2 b
                on substr(a.firstfield,10,20) = 
                   substr(b.anotherfield,1,10)
             where a.firstfield like 'BLAH%' 
            

            这种类型的东西只要有少量的语法变化,就可以在 Oracle 或 SQL Server 上运行,并且(尽管我没有要测试的 DB/2 实例)几乎肯定可以在 DB/2 上运行。

            【讨论】:

            • 感谢 ConcernedOfTunbridge - 不幸的是,这在 DB2 中不起作用,我收到一条错误消息“列限定符或表 B 未定义”
            • 你试过了吗||而不是 +,并且您想键入内部联接而不是 'join' - 我认为 substr 函数应该是 '10, 10' 而不是 '10, 20' 请参阅 publib.boulder.ibm.com/infocenter/db2luw/v8/index.jsp?topic=/…
            • 标准 SQL 不支持 UPDATE 语句中的 JOIN... 这是 SQL Server 语法; MySQL 支持 UPDATE 语句中的 JOINS,但不支持该语法。
            【解决方案9】:
            UPDATE tes_1  a
            SET a.nama = 
            (SELECT b.nama FROM tes_2 b WHERE a.urut = b.urut )
            

            【讨论】:

            • 它如何解决“有没有办法在更新语句中使用 joins”这个问题?
            【解决方案10】:

            DB2 LUW 9.7 上the UPDATE statement 的参考文档提供了以下示例:

               UPDATE (SELECT EMPNO, SALARY, COMM,
                 AVG(SALARY) OVER (PARTITION BY WORKDEPT),
                 AVG(COMM) OVER (PARTITION BY WORKDEPT)
                 FROM EMPLOYEE E) AS E(EMPNO, SALARY, COMM, AVGSAL, AVGCOMM)
               SET (SALARY, COMM) = (AVGSAL, AVGCOMM)
               WHERE EMPNO = '000120'
            

            UPDATE 之后的括号可以包含一个全选,这意味着任何有效的 SELECT 语句都可以到那里。

            基于此,我建议如下:

            UPDATE (
              SELECT
                f1.firstfield,
                f2.anotherfield,
                f2.something
              FROM file1 f1
              WHERE f1.firstfield like 'BLAH%' 
              INNER JOIN file2 f2
              ON substr(f1.firstfield,10,20) = substr(f2.anotherfield,1,10)
            )
            AS my_files(firstfield, anotherfield, something)
            SET
              firstfield = ( 'BIT OF TEXT' || something )
            

            编辑:伊恩是对的。我的第一反应是尝试子选择:

            UPDATE file1 f1
            SET f1.firstfield = ( 'BIT OF TEXT' || (
              SELECT f2.something
              FROM file2 f2
              WHERE substr(f1.firstfield,10,20) = substr(f2.anotherfield,1,10)
            ))
            WHERE f1.firstfield LIKE 'BLAH%' 
            AND substr(f1.firstfield,10,20) IN (
              SELECT substr(f2.anotherfield,1,10)
              FROM file2 f2
            )
            

            但我不确定串联是否有效。它还假设子字符串之间存在 1:1 映射。如果有多个匹配的行,它将不起作用。

            【讨论】:

            • 您无法更新包含连接的全选 - 就像您无法更新包含连接的视图(没有 INSTEAD OF 触发器)。该语句将返回 SQL01050N。
            【解决方案11】:

            在 DB2 上是这样的:

            UPDATE TABLE
            set TABLE.firstfield = ( 'BIT OF TEXT' concat TABLE.something )                                                                             
            where TABLE.firstfield like 'BLAH%'   
            

            【讨论】:

            • 它如何解决“有没有办法在更新语句中使用 joins”这个问题?
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2013-07-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多