使用来自不同行源的相同密钥更新行
Update lines with same key from diffents lines source
我有以下 table 表 1:
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 个。
现在,我在 table 表 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(),但不支持该功能。
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
您还没有说明如何匹配表 1 中的哪一行与表 2 中的哪一行。
建议的连接列在两个表中具有 *相同* 值;最终结果是,在建议的连接列上连接这 2 个表将导致 9 行笛卡尔积(表 2 中的每一行与表 1 中的每一行匹配)。
我猜答案是……对于表 2 中的每一行,连接到表 1 中的任何一行……这个问答的全部目的是如何将每个连接限制为表 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 具有相同的列集(相同的列名,相同的数据类型)......鉴于您提供的示例数据,这似乎是一个有效的假设。
注意:我无权访问 IQ 数据库;我确实可以访问 SQLAnywhere 数据库;下面使用的函数确实出现在 IQ 参考手册中;建议的解决方案适用于我的 SQLAnywhere 数据库;最终结果是以下内容应该适用于 IQ ... >>交叉手指<< ...
首先是一些背景:
1 - table 中的每条记录都有一个唯一的行 ID,可以通过 rowid(<table_name>)
函数
访问
2 - number()
函数可用于为结果集生成唯一编号(以 1
开头)但是,此函数不能用于子查询或派生 table(这意味着我们不能在我们的 UPDATE 语句中包含派生的 tables)
解决方案的要点:
1 - 将 Table1 和 Table2 中的所需行拉入 #temp tables,使用 number()
函数为每组 #temp [生成唯一的行号(从 1 开始)table记录;还为 Table1
拉 rowid()
2 - 编写我们的 UPDATE 语句来引用我们的#temp tables,根据它们的行号(由 number()
函数生成)连接唯一的 #temp table 行对), 并通过 rowid()
值
返回主 table
设置:
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
Build/populate #temp tables:
-- 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
我有以下 table 表 1:
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 个。
现在,我在 table 表 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(),但不支持该功能。
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
您还没有说明如何匹配表 1 中的哪一行与表 2 中的哪一行。
建议的连接列在两个表中具有 *相同* 值;最终结果是,在建议的连接列上连接这 2 个表将导致 9 行笛卡尔积(表 2 中的每一行与表 1 中的每一行匹配)。
我猜答案是……对于表 2 中的每一行,连接到表 1 中的任何一行……这个问答的全部目的是如何将每个连接限制为表 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 具有相同的列集(相同的列名,相同的数据类型)......鉴于您提供的示例数据,这似乎是一个有效的假设。
注意:我无权访问 IQ 数据库;我确实可以访问 SQLAnywhere 数据库;下面使用的函数确实出现在 IQ 参考手册中;建议的解决方案适用于我的 SQLAnywhere 数据库;最终结果是以下内容应该适用于 IQ ... >>交叉手指<< ...
首先是一些背景:
1 - table 中的每条记录都有一个唯一的行 ID,可以通过 rowid(<table_name>)
函数
2 - number()
函数可用于为结果集生成唯一编号(以 1
开头)但是,此函数不能用于子查询或派生 table(这意味着我们不能在我们的 UPDATE 语句中包含派生的 tables)
解决方案的要点:
1 - 将 Table1 和 Table2 中的所需行拉入 #temp tables,使用 number()
函数为每组 #temp [生成唯一的行号(从 1 开始)table记录;还为 Table1
rowid()
2 - 编写我们的 UPDATE 语句来引用我们的#temp tables,根据它们的行号(由 number()
函数生成)连接唯一的 #temp table 行对), 并通过 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
Build/populate #temp tables:
-- 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