【问题标题】:Update using subquery and Case statements使用子查询和 Case 语句进行更新
【发布时间】:2017-02-20 12:07:53
【问题描述】:

我正在编写一个带有一些案例语句的更新查询。当大小写不满足时,它将使用 NULL 更新列。
以下是查询:

 UPDATE TGT
 SET C1 = CASE WHEN TGT.c2 = SRC.c2 AND SRC.C3 = 'P' THEN SRC.C1 ELSE NULL END,
     C4 = CASE WHEN TGT.c5 = SRC.c5 AND SRC.C3 = 'D' THEN SRC.C4 ELSE NULL END
    FROM SRC;

即使源表中存在数据,它也始终填充 NULL。

提前感谢您的帮助。

【问题讨论】:

  • 此查询是否运行,没有更新任何内容,还是给出错误?
  • 不,这是一个单一的查询。它更新表中的所有记录,但只有 NULL 值。
  • 这是甲骨文吗?
  • 这是无效的语法。您可能在子查询中有那个 CASE?如 SET C1 = (SELECT CASE ...)?
  • Oracle 和 Vetica。

标签: sql oracle vertica


【解决方案1】:

Oracle 不支持update 语句中的fromjoin。但是,您可以使用子查询:

UPDATE TGT
    SET C1 = (CASE WHEN EXISTS (SELECT 1
                                FROM SRC
                                WHERE TGT.c2 = SRC.c2 AND SRC.C3 = 'P'
                   THEN TGT.C1 ELSE NULL
              END);

注意:以上将更新所有行。如果您只想更新不匹配的行,请在where 子句中使用not exists

UPDATE TGT
    SET C1 = NULL
    WHERE NOT EXISTS (SELECT 1
                      FROM SRC
                      WHERE TGT.c2 = SRC.c2 AND SRC.C3 = 'P'
                     );

【讨论】:

  • 这可以在我们只更新 1 列时尝试。如果需要更新超过 1 列,那么它将无济于事。我猜它也可能会带来性能问题。有什么想法吗??
  • @Biswabid:如果您需要更新不止一列,请使用 set (c1, c2, c3) = (select x1, x2, x3 from ...)
【解决方案2】:

如果src 中不存在相关的“P”记录,您想将c1 设置为空。因此使用NOT EXISTS

UPDATE tgt
SET c1 = NULL
WHERE NOT EXISTS
(
  SELECT *
  FROM src
  WHERE src.c2 = tgt.c2 =  AND src.c3 = 'P'
);

更新:您刚刚更改了问题,现在您希望在两种不同的情况下将两个不同的字段设置为 null。我建议你简单地使用两个语句:上面的 c1 和类似的 c4。没有必要把事情弄得比实际更复杂。

【讨论】:

    猜你喜欢
    • 2016-04-10
    • 1970-01-01
    • 2013-08-29
    • 1970-01-01
    • 2023-03-08
    • 2011-02-14
    • 1970-01-01
    • 1970-01-01
    • 2011-05-30
    相关资源
    最近更新 更多