ОБНОВЛЕНИЕ SQL с несколькими условиями WHERE (отношения)

Я хотел бы знать, возможно ли выполнить такое ОБНОВЛЕНИЕ в базе данных Oracle SQL:

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 как условие, но с другой стороны, я не вижу причины, почему это не работает.

ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
3
0
66
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы не можете ссылаться на еще две таблицы (CLASSES и SUBJECT) Просто так из ниоткуда. Вот код, который показывает как, возможно, вы это сделали:

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 27.04.2019 16:17

Это установит mark на NULL, если нет совпадающих значений. Я не думаю, что это то, что имеет в виду ОП. Он также излишне обновляет строки.

Gordon Linoff 27.04.2019 16:24

О, теперь я понимаю, что вы имели в виду, право должно быть обновлено с помощью оператора if EXIST или sth.

dante 27.04.2019 16:30

Вот что означает ... позади WHERE.

Littlefoot 27.04.2019 16:50
Ответ принят как подходящий

Вы можете использовать подзапрос:

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, поэтому обновляются только те строки, которые необходимо обновить.

Тоже отлично работает, даже проще на мой взгляд большое спасибо.

dante 27.04.2019 16:18

Я считаю, что в подобных случаях оператор 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 28.04.2019 12:34

Другие вопросы по теме