首先,SQL不是我的优势。所以我需要帮助解决以下问题。我将简化表格内容来描述问题。
让我们从三个表开始:table1
列id_1
和value
,table2
列id_2
和value
,table3
列id_3
和value
。正如您所注意到的,所有三个表中都显示一个字段value
,而ID具有不同的列名。 修改列名不是一个选项,因为它们由Java遗留代码使用。
我需要根据字段table3.value
,table1.value
和table2.value
使用table1.id_1
或table2.id_2
设置table3.id_3
。
我的最后一次尝试,描述了我尝试做的事情,如下:
UPDATE table3
SET value=(IF ((SELECT COUNT(\*) FROM table1 t1 WHERE t1.id_1=id_3) > 0)
SELECT value FROM table1 t1 WHERE t1.id_1=id_3
ELSE IF ((SELECT COUNT(\*) FROM table2 t2 WHERE t2.id_2=id_3)) > 0)
SELECT value FROM table2 t2 WHERE t2.id_2=id_3)
以下是有关表格和更新的一些信息。
table3.id_3
的ID最多可在table1.id_1
或table2.id_2
中找到一次,但不能同时在两个表中找到。table3.id_3
或table1.id_1
中找不到table2.id_2
,则table3.value
仍然为空。你可以想象,我的最后一次尝试失败了。在这种情况下,在Liquibase更新期间无法识别IF
命令。如果有人有任何想法如何处理这个,我很感激。提前谢谢。
答案 0 :(得分:1)
我不太了解Oracle
,但使用COALESCE()
和OUTER JOIN
的SQL Server
方法将是以下方法。
Update T3
Set Value = Coalesce(T1.Value, T2.Value)
From Table3 T3
Left Join Table2 T2 On T3.Id_3 = T2.Id_2
Left Join Table1 T1 On T3.Id_3 = T1.Id_1
COALESCE()
会将LEFT JOIN
中的第一个非NULL
值返回到表1
和2
,如果找不到记录,或者,它将被设置为NULL
。
答案 1 :(得分:1)
用UPDATE
运算符编写的Siyual MERGE
。
MERGE into table_1
USING (
SELECT COALESCE(t2.value, t3.value) as value, t1.id_1 as id
FROM table_1 t1, table_2 t2, table_3 t3
WHERE t2.id_2 = t3.id_3 and t1.id_1 = t2.id_2
) t on (table_1.id_1 = t.id)
WHEN MATCHED THEN
UPDATE SET table_1.value = t.value
这应该适用于Oracle。
答案 2 :(得分:0)
在Oracle中
UPDATE table3 t
SET value=COALESCE((SELECT value FROM table1 t1 WHERE t1.id_1=t.id_3),
(SELECT value FROM table2 t2 WHERE t2.id_2=t.id_3))
答案 3 :(得分:0)
鉴于您的假设#3,您可以使用union all
将表1和表2放在一起,而不会冒重复信息的风险(至少对于感兴趣的ID)。因此,如下所示的简单merge
解决方案应该有效(在所有实现merge
操作的数据库产品中)。
merge into table3
using (
select id_2 as id, value from table2
union all
select id_3, value from table 3
) t
on table3.id_3 = t.id
when matched
then update set table3.value = t.value;
您可能希望测试各种解决方案,看看哪种解决方案对您的特定表格最有效。
(注意:merge
应该比使用update
的{{1}}解决方案更有效,至少当表3中相对较少的id匹配时在其他表中。这是因为coalesce
解决方案将重新插入NULL,其中在没有匹配时已经存储了NULL。update
解决方案避免了这种不必要的活动。)