我有两个表,一个是位置表,另一个是查找表。我必须查看查找表中的位置值,如果它们存在,则将它们与相应的值一起标记为“y”和“n”
我写了如下个人更新声明:
**Location1,L1value**
Update Location
set (Location1,L1value) =
(select UPPER(VAlue),'Y' from Location_lookup where trim(Location1)=Location
where exists (select 1 from Location_lookup where trim(Location1)=Location);
commit;
**Location2,value**
Update Location
set (Location2,L2value) =
(select UPPER(VAlue),'Y' from Location_lookup where trim(Location2)=Location
where exists (select 1 from Location_lookup where trim(Location2)=Location);
commit;
第三个标志和值也是如此。
有没有一种方法可以为这三个条件编写一个更新?为什么我要寻找单一的更新是因为我有1000多万条记录,我不想扫描记录三次不同的时间。查找表有超过3200万条记录。
1条答案
按热度按时间dxxyhpgq1#
这里有一个解决方案,它使用oracle的大容量。。。更新功能。这并不像纯sql解决方案那样具有很高的性能,但是它更易于编码,而且对于现代企业服务器上的1000万行来说,效率差异可能不会有多大影响,特别是如果这是一个一次性的练习的话。
注意事项:
你不能说位置是否有主键。对于这个答案,我假设它有一个id列。如果没有主键,解决方案将不起作用,但是如果表没有主键,则可能会遇到更大的问题。
您的问题提到将标志列设置为“y”和“n”,但所需的输出仅显示
'Y'
设置。我已经包括处理'N'
但看看下面的尾声。这里有一个关于db<>fiddle的工作演示。演示输出与查询中发布的示例输出不完全匹配,因为这与给定的输入数据不匹配。
将标志设置为“y”或“n”?
上面的代码在查找表上使用左外部联接。如果找到一行,nvl2()函数将返回“y”,否则返回“n”。这意味着无论值列是否为空,标志列总是被填充的。例外情况是在位置查找中没有与任何位置匹配的行(
ID=4000
在我的演示中)。在这种情况下,标志列将为空。这种不一致性源于问题中的不一致性。解决方法:
如果希望所有标志列都填充
'N'
从中删除where子句get_locations
游标查询。如果不想将标志设置为
'N'
相应地更改nvl2()函数调用:nvl2(lup1.value, 'Y', null) as l1flag