【问题标题】:SQL UPDATE with multiple WHERE (relations) conditions具有多个 WHERE(关系)条件的 SQL UPDATE
【发布时间】:2019-09-16 18:36:22
【问题描述】:

我想知道是否可以在 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 的条件可能会很愚蠢,但另一方面我看不出它不起作用的原因。

【问题讨论】:

    标签: sql oracle plsql oracle-sqldeveloper


    【解决方案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 子句,因此只更新需要更新的行。

    【讨论】:

    • 也可以正常工作,在我看来更简单,非常感谢。
    【解决方案2】:

    你不能引用另外两个表(CLASSESSUBJECT就像那样,不知从何而来。下面的代码显示了如何你可能已经做到了:

    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 子句来限制要更新的行数。

    【讨论】:

    • 是的,它可以工作,感谢您解释问题所在。
    • 如果没有匹配值,这会将mark 设置为NULL。我认为这不是 OP 的意图。它还会不必要地更新行。
    • 哦,现在我明白你的意思了,正确的应该更新为 if EXIST 或 sth 语句。
    • 这就是WHERE后面的...的意思。
    【解决方案3】:

    我发现在这种情况下,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
    

    祝你好运。

    【讨论】:

    • 欣赏另一种方法:)
    猜你喜欢
    • 2013-06-28
    • 2020-12-13
    • 1970-01-01
    • 2020-06-16
    • 1970-01-01
    • 2023-02-21
    • 2012-02-23
    • 2015-01-17
    • 1970-01-01
    相关资源
    最近更新 更多