Sql 如何选择可以来自两个不同表的值?

Sql 如何选择可以来自两个不同表的值?,sql,sql-server,oracle,liquibase,Sql,Sql Server,Oracle,Liquibase,首先,SQL不是我的强项。因此,我需要以下问题的帮助。我将简化表格内容来描述问题 让我们从三个表开始:表1包含列id_1和值,表2包含列id_2和值,表3包含列id_3和值。正如您所注意到的,字段值出现在所有三个表中,而ID具有不同的列名。修改列名不是一个选项,因为Java遗留代码使用列名 我需要根据table1.id_1、table2.id_2和table3.id_3字段,使用table1.value或table2.value设置table3.value 我的最后一次尝试描述了我尝试做的事情,

首先,SQL不是我的强项。因此,我需要以下问题的帮助。我将简化表格内容来描述问题

让我们从三个表开始:表1包含列id_1和值,表2包含列id_2和值,表3包含列id_3和值。正如您所注意到的,字段值出现在所有三个表中,而ID具有不同的列名。修改列名不是一个选项,因为Java遗留代码使用列名

我需要根据table1.id_1、table2.id_2和table3.id_3字段,使用table1.value或table2.value设置table3.value

我的最后一次尝试描述了我尝试做的事情,如下所示:

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)
下面是关于表和更新的一些信息

此更新将包含在Liquibase使用的XML文件中。 它必须与Oracle或SQL Server配合使用。 在表1.id_1或表2.id_2中最多只能找到一个表3.id_3中的id,但不能同时在两个表中找到。 如果在table1.id_1和table2.id_2中都找不到table3.id_3,则table3.value将保持为空。 你可以想象,我最后一次尝试失败了。在这种情况下,在Liquibase更新期间无法识别IF命令。如果有人知道如何处理这个问题,我将不胜感激。提前感谢。

我对Oracle不太了解,但SQL Server的方法是使用和

将从返回到表1和表2中的第一个非空值,如果在这两个表中均未找到记录,则将其设置为空。

这是Siyual使用合并运算符编写的更新

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中起作用。

在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,您可以使用union all将表1和表2放在一起,而不必承担至少为感兴趣的id复制信息的风险。因此,下面这样一个简单的合并解决方案应该适用于所有实现合并操作的DB产品

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应该比使用coalesce的更新解决方案更有效,至少当表3中的id与其他表中的id相对较少时是如此。这是因为当不存在匹配项时,更新解决方案将在已存储NULL的位置重新插入NULL。合并解决方案避免了这种不必要的活动。

COALESE函数在Oracle中的工作方式与此相同。这应该可以解决存在的问题。既然OP希望它在T1或T2中找不到时保持为NULL,我就把它添加到合并中,不是吗?或者是这样。但确切地说,应该如何做到这一点是与联合@SergeiPodlipaev是的,但我不确定更新语法是否相同。不过,问题是SQL Server还是Oracle,所以我认为这两种实现都可以。@scsimon不需要向COALESCE添加NULL。如果所有参数都为NULL,结果将为NULL。明白了,我想您需要将merge写入表_1。。。。。至少在Oracle和SQL标准中是这样。此外,对于手头的问题来说,这三个表的联接似乎过多了。
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;