如何 select 一个可以来自两个不同表的值?

How to select a value that can come from two different tables?

首先,SQL不是我的强项。所以我需要帮助解决以下问题。我将简化table内容来描述问题。

让我们从三个 table 开始:table1 包含 id_1value 列,table2 包含 id_2valuetable3id_3value。您会注意到,字段 value 出现在所有三个 table 中,而 id 具有不同的列名。 修改列名不是一个选项,因为它们被Java 遗留代码使用。

我需要根据字段 table1.id_1table2.id_2table3.id_3 使用 table1.valuetable2.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)

这里有一些关于 table 和更新的信息。

  1. 此更新将包含在 Liquibase 使用的 XML 文件中。
  2. 它必须与 OracleSQL Server.
  3. 配合使用
  4. 来自 table3.id_3 的 ID 最多只能在 table1.id_1table2.id_2 中找到一次,但不能同时在两个 table 中找到。
  5. 如果 table3.id_3table1.id_1table2.id_2 中均未找到,则 table3.value 保持为空。

如你所想,我最后一次尝试失败了。在这种情况下,Liquibase 更新期间无法识别 IF 命令。如果有人对如何处理此问题有任何想法,我将不胜感激。提前致谢。

我不太了解 Oracle,但是 SQL Server 方法如下使用 COALESCE() and OUTER JOINs.

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

12COALESCE() will return the first non-NULL value from the LEFT JOIN,如果在任何一个中都没有找到记录,它将被设置为NULL

是Siyual的UPDATEMERGE运算符写的

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。

在甲骨文中

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)。因此,像下面这样的简单 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 应该比使用 coalesceupdate 解决方案更有效,至少当 id 相对较少时在 table3 中在其他表中有匹配。这是因为 update 解决方案将在没有匹配时重新插入 NULL,其中 NULL 已存储。merge 解决方案避免了这种不必要的 activity.)