【问题标题】:Update lines with same key from diffents lines source从不同的行源更新具有相同键的行
【发布时间】:2017-07-28 00:57:08
【问题描述】:

我有下表Table1:

numseq  Article     ID          Num1        Num2    Num3   Num4    Col07    Col08
3023    F           242840794       4           12        1    13          RCN03    9   
3023    F           242840794       4           12        1    13          RCN03    9   
3023    F           242840794       4           12        1    13          RCN03    9   

Col07 的值为 false,5 个字符不是 6 个。

现在,我在表 Table2 中有更正的数据

numseq  Article     ID              Num1        Num2    Num3   Num4    Col07     Col08
3023    F           242840794       4           12        1    13      RCN031    9   
3023    F           242840794       4           12        1    13      RCN035    9   
3023    F           242840794       4           12        1    13      RCN037    9   

更新 Table1.Col07 的关键是所有其他列。

如何进行更新?

我使用 Sybase IQ 15.1。

我尝试使用 row_number(),但该函数不受支持。

【问题讨论】:

    标签: sql sap-iq


    【解决方案1】:

    Sybase 在update 中支持join

    update t1
        set col7 = t2.col7
        from table1 t1 join
             table2 t2
             on t1.numseq = t2.numseq and
                t1.article = t2.article and
                . . . ;  -- I'm not sure which columns are needed for matching
    

    【讨论】:

    • OP 的问题提到“更新 Table1 的关键是所有其他列”。以下是其余的专栏,基于我正在写的答案(你忍者!:P):t1.numseq=t2.numseq and t1.Article=t2.Article and t1.ID=t2.ID and t1.Num1=t2.Num1 and t1.Num2=t2.Num2 and t1.Num4=t2.Num4 and t1.Col08=t2.Col08
    • @RobbieToyota,(我认为)Gordon 试图说明的是我们正在处理 3 组相同的连接列值(Table1 和 Table2),最终结果是每一行in Table2 将加入 Table1 中的所有 3 行(即,笛卡尔积);那么,如何确保 9 个连接执行所需的 3 个更新?
    【解决方案2】:

    您还没有说明如何将 Table1 中的哪一行与 Table2 中的哪一行匹配。

    建议的连接列在两个表中具有 *相同* 值;最终结果是在建议的连接列上连接这 2 个表将导致 9 行笛卡尔积(Table2 中的每一行与 Table1 中的每一行匹配)。

    我猜答案是这样的……对于 Table2 中的每一行,加入 Table1 中的任何一行……本问答的全部目的是如何将每个连接限制为单个表 1 中的行。

    虽然可能有一些巧妙的方法可以做到这一点(注意:我不使用 IQ),但我认为以下可能更容易实现并且可能更容易理解:

    begin tran
    
    delete Table1 where ... >>conditions that match the 3 duplicate rows<< ...
    
    insert Table1 select * from Table2 where ... >>conditions that match the 3 new rows<< ...
    
    if no errors
        commit tran
    else
        rollback tran
        generate additional error message ?
    

    注意:显然(?)以上假设 Table1 和 Table2 具有相同的列集(相同的列名,相同的数据类型)...鉴于您提供的示例数据,这似乎是一个有效的假设。

    【讨论】:

    • "对于 Table2 中的每一行,加入 Table1 中的任何一行":就是这样。我真的不在乎 Table2 中的哪一个更新 Table1 中的哪一个,因为这将是相同的结果。我不能像在 Table1 中那样执行删除/插入操作,其他列也完全相同,但在 Table2 中没有。
    • 是的,我想你会回来评论表中的其他列;假设您有权创建#temp 表......我正在写另一个基于#temp 表的答案,应该(敲木头)完成这项工作......应该在接下来的 5-10 分钟内发布......
    • 我确实有可能创建临时表
    【解决方案3】:

    注意:我无权访问 IQ 数据库;我确实可以访问 SQLAnywhere 数据库;下面使用的函数确实出现在 IQ 参考手册中;建议的解决方案适用于我的 SQLAnywhere 数据库;最终结果是以下应该在 IQ 中起作用 ... >>交叉手指

    先介绍一下背景:

    1 - 表中的每条记录都有一个唯一的行 ID,可以通过 rowid(&lt;table_name&gt;) 函数访问

    2 - number() 函数可用于为结果集生成唯一编号(以 1 开头)但是,此函数不能用于子查询或派生表(这意味着我们可以' t 在我们的 UPDATE 语句中合并派生表)

    解决方案要点:

    1 - 使用number()函数为每组#temp表记录生成唯一的行号(从1开始)从Table1和Table2中提取所需的行到#temp表中;还为 Table1 拉rowid()

    2 - 编写我们的 UPDATE 语句来引用我们的 #temp 表,根据行号(由 number() 函数生成)连接唯一的 #temp 表行对,并通过 @987654327 连接回主表@值

    设置:

    create table Table1 (numseq int, Article char(1), ID int, Num1 int, Num2 int, Num3 int, Num4 int, Col07 varchar(10), Col08 int)
    go
    create table Table2 (numseq int, Article char(1), ID int, Num1 int, Num2 int, Num3 int, Num4 int, Col07 varchar(10), Col08 int)
    go
    
    insert Table1 values (3023,'F',242840794,4,12,1,13,'RCN03',9)
    insert Table1 values (3023,'F',242840794,4,12,1,13,'RCN03',9)
    insert Table1 values (3023,'F',242840794,4,12,1,13,'RCN03',9)
    go
    
    insert Table2 values (3023,'F',242840794,4,12,1,13,'RCN031',9)
    insert Table2 values (3023,'F',242840794,4,12,1,13,'RCN035',9)
    insert Table2 values (3023,'F',242840794,4,12,1,13,'RCN037',9)
    go
    
     numseq      Article ID          Num1        Num2        Num3        Num4        Col07      Col08
     ----------- ------- ----------- ----------- ----------- ----------- ----------- ---------- -----------
            3023 F         242840794           4          12           1          13 RCN03                9
            3023 F         242840794           4          12           1          13 RCN03                9
            3023 F         242840794           4          12           1          13 RCN03                9
    
     numseq      Article ID          Num1        Num2        Num3        Num4        Col07      Col08
     ----------- ------- ----------- ----------- ----------- ----------- ----------- ---------- -----------
            3023 F         242840794           4          12           1          13 RCN031               9
            3023 F         242840794           4          12           1          13 RCN035               9
            3023 F         242840794           4          12           1          13 RCN037               9
    

    构建/填充#temp 表:

    -- we'll use WHERE clauses in our 'select/into' statements in case you
    -- are planning on processing just a subset of Table1 and/or Table2; and
    -- while the 'order by' clauses aren't needed for this simple example, you 
    -- will need to include them if you plan on updating multiple sets of 
    -- duplicate rows at the same time (ie, you need to make sure the number() 
    -- values match between sets of duplicate rows)
    
    select rowid(Table1) as rid, number() as nbr, * into #t1 from Table1 where numseq = 3023 and Article = 'F' and ID = 242840794 and Num1 = 4 and Num2 = 12 and Num3 = 1 and Num4 = 13 and Col08 = 9
        order by numseq, Article, ID, Num1, Num2, Num3, Num4, Col08
    go
    select                       number() as nbr, * into #t2 from Table2 where numseq = 3023 and Article = 'F' and ID = 242840794 and Num1 = 4 and Num2 = 12 and Num3 = 1 and Num4 = 13 and Col08 = 9
        order by numseq, Article, ID, Num1, Num2, Num3, Num4, Col08
    go
    
    select * from #t1
    select * from #t2
    go
    
     rid                  nbr         numseq      Article ID          Num1        Num2        Num3        Num4        Col07      Col08
     -------------------- ----------- ----------- ------- ----------- ----------- ----------- ----------- ----------- ---------- -----------
                 68222976           1        3023 F         242840794           4          12           1          13 RCN03                9
                 68222977           2        3023 F         242840794           4          12           1          13 RCN03                9
                 68222978           3        3023 F         242840794           4          12           1          13 RCN03                9
    
     nbr         numseq      Article ID          Num1        Num2        Num3        Num4        Col07      Col08
     ----------- ----------- ------- ----------- ----------- ----------- ----------- ----------- ---------- -----------
               1        3023 F         242840794           4          12           1          13 RCN031               9
               2        3023 F         242840794           4          12           1          13 RCN035               9
               3        3023 F         242840794           4          12           1          13 RCN037               9
    

    现在是更新:

    update  Table1
    
    set     Table1.Col07 = #t2.Col07
    
    from    Table1
    join    #t1
    
            -- rowid() is unique and thus the only 'column' we need in the join between Table1 and itself (aka #t1)
    
    on      rowid(Table1) = #t1.rid
    
            -- and the rest of the join columns between Table1 and #t1; optional 
    /*
    and     Table1.numseq      = #t1.numseq
    and     Table1.Article     = #t1.Article
    and     Table1.ID          = #t1.ID
    and     Table1.Num1        = #t1.Num1
    and     Table1.Num2        = #t1.Num2
    and     Table1.Num3        = #t1.Num3
    and     Table1.Num4        = #t1.Num4
    and     Table1.Col08       = #t1.Col08
    */
    
    join    #t2
    
            -- join on our number() values
    
    on      #t1.nbr         = #t2.nbr
    
            -- and the rest of the join columns between #t1 and #t2; optional but
            -- provides an extra safety check to make sure we don't update records
            -- with the wrong values (eg, number() is generated in wrong order)
    
    and     #t1.numseq      = #t2.numseq
    and     #t1.Article     = #t2.Article
    and     #t1.ID          = #t2.ID
    and     #t1.Num1        = #t2.Num1
    and     #t1.Num2        = #t2.Num2
    and     #t1.Num3        = #t2.Num3
    and     #t1.Num4        = #t2.Num4
    and     #t1.Col08       = #t2.Col08
    go
    
    select * from Table1
    go
    
     numseq      Article ID          Num1        Num2        Num3        Num4        Col07      Col08
     ----------- ------- ----------- ----------- ----------- ----------- ----------- ---------- -----------
            3023 F         242840794           4          12           1          13 RCN031               9
            3023 F         242840794           4          12           1          13 RCN035               9
            3023 F         242840794           4          12           1          13 RCN037               9
    

    【讨论】:

    • 这似乎是我需要的。我现在无法访问数据库,我明天试试。
    猜你喜欢
    • 2015-08-07
    • 1970-01-01
    • 2015-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-29
    相关资源
    最近更新 更多