使用来自不同行源的相同键更新行

时间:2017-07-26 16:26:19

标签: sql sybase-iq

我有下表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个。

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

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(),但不支持该功能。

3 个答案:

答案 0 :(得分:1)

Sybase支持join中的update

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

答案 1 :(得分:1)

您尚未说明如何将Table1中的哪一行与Table2中的哪一行匹配。

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

我猜这个答案是......对于Table2中的每一行,连接到Table1中的任何一行......这个Q& A的全部目的是如何将每个连接限制为表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具有相同的列集(相同的列名,相同的数据类型)......根据您提供的样本数据,这似乎是一个有效的假设。

答案 2 :(得分:0)

注意:我无法访问IQ数据库;我有权访问SQLAnywhere数据库;以下使用的功能确实显示在IQ参考手册中;建议的解决方案适用于我的SQLAnywhere数据库;最终结果是,以下内容应该适用于IQ ...&gt;&gt;交叉手指&lt;&lt; ...

首先是一些背景:

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

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

解决方案的要点:

1 - 将表1和表2中所需的行拉入#temp表,使用number()函数为每组#temp表记录生成唯一的行号(从1开始);同时拉取Table1的rowid()

2 - 编写我们的UPDATE语句以引用我们的#temp表,根据行号(由number()函数生成)连接唯一的#temp表行对,并通过以下方式连接回主表: rowid()

设定:

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