使用多个WHERE条件的SQL UPDATE(关系)语句

3
我想知道在Oracle SQL数据库中是否有可能执行这样的UPDATE操作:
UPDATE mark
        SET
        mark=
        CASE
        WHEN mark.val<= 5 
            THEN val*1.1
        ELSE val END
        WHERE mark.id_classes = classes.id_classes 
            AND classes.ID_subject = subject.ID_subject
            AND subject.ID_subject = 5;

在这部分,SQL开发人员返回错误:

WHERE mark.id_classes = classes.id_classes 
            AND classes.ID_subject = subject.ID_subject
            AND subject.ID_subject = 5;

那么我猜测不可能制作出如此复杂的条件,还有其他方法可以做到吗?

尝试更多类似SELECT的条件可能有些愚蠢,但另一方面我不明白为什么它不能工作。

3个回答

1
你不能像这样从无处引用另外两个表(CLASSESSUBJECT)。下面的代码展示了你可能是如何做到的:how
update mark m set
  m.mark = (select case when m.val <= 5 then m.val * 1.1
                        else m.val
                   end
            from classes c join subject s on c.id_subject = s.id_subject
            where c.id_classes = m.id_classes
              and s.id_subject = 5
           )
where ... 

由于您在CASE中没有使用表别名,我不知道VAL列属于哪个表(所以我假设它是MARK)。
此外,UPDATE本身可能需要WHERE子句来限制要更新的行数。

是的,它有效了,谢谢你解释问题所在。 - dante
如果没有匹配的值,这将把mark设置为NULL。我认为这不是原帖作者的意图。它还会不必要地更新行。 - Gordon Linoff
哦,现在我明白你的意思了,应该使用if EXIST或者其他语句来更新正确性。 - dante
这就是 WHERE 后面的 ... 的含义。 - Littlefoot

1
您可以使用子查询:

UPDATE mark
    SET mark = val * 1.1
    WHERE mark.val <= 5 AND
          EXISTS (SELECT 1
                  FROM classes c JOIN
                       subjects s
                       ON c.ID_subject = s.ID_subject
                  WHERE mark.id_classes = c.id_classes AND                       
                        s.ID_subject = 5
                 );

注意我将 CASE 条件移动到 WHERE 子句中,以便只更新需要更新的行。

1
在我看来,这个也很好用,甚至更加简单。非常感谢。 - dante

1

我发现在这种情况下,使用MERGE语句更容易理解:

MERGE INTO MARK m
  USING (SELECT c.ID_CLASSES
           FROM CLASSES c
           WHERE c.ID_SUBJECT = 5) d
    ON (m.ID_CLASSES = d.ID_CLASSES)
  WHEN MATCHED THEN
    UPDATE SET m.MARK = CASE
                          WHEN m.VAL <= 5 
                            THEN m.VAL * 1.1
                          ELSE
                             m.VAL
                        END

或者,由于ID_SUBJECT是一个常量,您可以简化您的更新为

UPDATE MARK m
  SET m.MARK = CASE
                 WHEN m.VAL <= 5 
                   THEN m.VAL * 1.1
                 ELSE
                   m.VAL
                 END
  WHERE m.ID_CLASSES = 5

祝你好运。


感谢另一种方法 :) - dante

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接