我有两个Oracle表,表车和表汽车。我正在更新Car以添加汽车品牌和型号中存在的两个字段。两个表都有3个外围键,Code1,Code2和Code3,它们将我们需要的至少一个键匹配以更新表格,并且列可以为空,因此我们必须小心。这些代码对于每个记录都是唯一的,除了我在下面提到的重复的情况。为了形象化,让我在这里制作表格:
桌车
ID | Code1 | Code2| Code3| Color | Salesman
1 1A2B3C 555HGG H1H1H1 Red John
2 2H4H6H 777JHH J1J1J1 Blue Steve
3 3J7K4A 222QYY I1I1I1 Yellow Maria
4 K2K2K2 Pink Clara
5 999YII Red Tim
Table Automobile
Code1| Code2| Code3 | Make | Model | ID
1A2B3C 555HGG H1H1H1 Nissan Sentra 234
2H4H6H J1J1J1 Chevy Malibu 235
K2K2K2 Nissan Maxima 236
K2K2K2 Nissan Maxima 237
999YII Ford Focus 238
更新了表车:
ID | Code1 | Code2| Code3| Color | Salesman | Make | Model
1 1A2B3C 555HGG H1H1H1 Red John Nissan Sentra
2 2H4H6H 777JHH J1J1J1 Blue Steve Chevy Malibu
3 3J7K4A 222QYY I1I1I1 Yellow Maria
4 K2K2K2 Pink Clara Nissan Maxima
5 999YII Red Tim Ford Focus
所以Table Car最初没有Make和Model字段,但我们需要从table Automobile中获取。假设现在表中存在字段,只需要填充。此外,您可以在表汽车的日产千里马示例中看到具有唯一ID的重复记录。在那种情况下,我只需要其中一条记录并不重要,因为来自汽车的ID无关紧要且不需要。两个ID字段没有连接。将填充至少一个代码字段,永远不会出现全部为空的情况。我知道这是一个有点混乱的问题,所以如果你需要澄清请求,我会调整我的OP。此外,这也是针对Oracle的,请记住这一点。任何帮助将不胜感激,这已经困扰了我好几天。
答案 0 :(得分:0)
以下使用row_number()
获取一行,然后匹配代码:
select c.*, a.make, a.model
from car c left join
(select a.*,
row_number() over (partition by code1, code2, code3 order by id) as seqnum
from automobile a
) a
on (c.code1 = a.code1 or c.code1 is null and a.code1 is null) and
(c.code2 = a.code2 or c.code2 is null and a.code2 is null) and
(c.code3 = a.code2 or c.code3 is null and a.code3 is null) and
a.seqnum = 1
答案 1 :(得分:0)
加入OR
条件非常慢,因为它们无法利用列上的索引。 (如果您在表中的Code1
,Code2
和Code3
上有索引,将会有所帮助。)我宁愿将作业分成三个单独的更新,一次只使用一列。此外,在第二次和第三次更新中,我将检查新列中的NULL
以确保我不将行更新为它已包含的相同值(这可能看起来像一个小问题,但撤消和重做可能会在冗余分配之上增加大量开销。)
由于您需要对Automobile
表进行重复数据删除,因此最好创建一个临时表(因为您将使用它三次)。类似的东西:
create global temporary table auto
on commit preserve rows -- if you want to commit after each update
as (
select code1, code2, code3, min(make) as make, min(model) as model
from automobile
group by code1, code2, code3
)
然后第二次更新,使用code2
(code3
将类似,code1
不需要where
子句。您会看到我更喜欢merge
语句,但您可以将update
与联接一起使用。
merge into car c
using auto a
on (c.code2 = a.code2)
when matched then update
set c.make = a.make,
c.model = a.model
where c.make is null
;