SQL UPDATE SET один столбец должен быть равен значению в связанной таблице, на которую ссылается другой столбец?

112

Надеюсь, это имело смысл, позвольте мне уточнить:

Для программы викторины есть таблица данных отслеживания, в каждой строке которой есть ..

QuestionID и AnswerID (для каждого есть таблица). Таким образом, из-за ошибки для группы QuestionID было задано значение NULL, но QuestionID соответствующего AnswerID находится в таблице ответов.

Скажем, QuestionID равен NULL, а AnswerID - 500, если мы перейдем к таблице ответов и найдем AnswerID 500, появится столбец с идентификатором QuestionID, который должен был быть там, где значение NULL.

Поэтому в основном я хочу установить каждый NULL QuestionID равным идентификатору QuestionID, найденному в таблице ответов в строке ответа AnswerID, который находится в таблице отслеживания (та же строка, что и записываемый NULL QuestionID).

Как бы я это сделал?

UPDATE QuestionTrackings
SET QuestionID = (need some select query that will get the QuestionID from the AnswerID in this row)
WHERE QuestionID is NULL AND ... ?

Не уверен, как я смогу заставить его назначить QuestionID для QuestionID из соответствующего AnswerID ...

CloudMeta
источник
MySQL и Microsoft SQL Server поддерживают расширения синтаксиса SQL для поддержки многотабличного UPDATE. Другие бренды этого не делают. Вы не сказали, какой бренд базы данных используете.
Билл Карвин,

Ответы:

171
update q
set q.QuestionID = a.QuestionID
from QuestionTrackings q
inner join QuestionAnswers a
on q.AnswerID = a.AnswerID
where q.QuestionID is null -- and other conditions you might want

Я рекомендую проверить, какой набор результатов для обновления, перед запуском обновления (тот же запрос, только с выбором):

select *
from QuestionTrackings q
inner join QuestionAnswers a
on q.AnswerID = a.AnswerID
where q.QuestionID is null -- and other conditions you might want

В частности, имеет ли каждый идентификатор ответа только 1 связанный идентификатор вопроса.

eglasius
источник
7
Я не уверен, почему, но у меня это не работает, однако это работает: update QuestionTrackings q inner join QuestionAnswers a on q.AnswerID = a.AnswerID set q.QuestionID = a.QuestionID; похоже, тот же базовый запрос в другом порядке. есть идеи почему?
billynoah
2
@billynoah, ORA-00971: отсутствует ключевое слово SET в Oracle
masT
2
Возникла проблема с аналогичной ситуацией в PhpMyAdmin поверх MySQL. В моем случае исходный и целевой столбцы находятся в одной таблице, но выбор записи основан на другой таблице. Версия запроса «SELECT» работает, но оператор UPDTATE выдает синтаксическую ошибку в «FROM»
2NinerRomeo,
3
Я UPDATE table1 NATURAL JOIN table2 SET table1.col1 = table1.col2 WHERE table2.col3 ="condition"
решил
является ли "q" из "update q" в ответе буквальным параметром запроса или это просто ваше сокращение для имени таблицы?
Шон
28

Без нотации обновления и соединения (не все СУБД поддерживают это) используйте:

UPDATE QuestionTrackings
   SET QuestionID = (SELECT QuestionID
                        FROM AnswerTrackings
                        WHERE AnswerTrackings.AnswerID = QuestionTrackings.AnswerID)
   WHERE QuestionID IS NULL
     AND EXISTS(SELECT QuestionID
                        FROM AnswerTrackings
                        WHERE AnswerTrackings.AnswerID = QuestionTrackings.AnswerID)

Часто в таком запросе вам необходимо дополнить предложение WHERE предложением EXISTS, содержащим подзапрос. Это предотвращает попадание UPDATE в строки, где нет совпадений (обычно обнуление всех значений). В этом случае, поскольку отсутствующий идентификатор вопроса изменит NULL на NULL, возможно, это не имеет значения.

Джонатан Леффлер
источник
Этот метод работал у меня в Oracle 12c (где метод соединения обновления не удался).
shwartz
16

Я не знаю, столкнулись ли вы с той же проблемой, что и я, в MySQL Workbench, но выполнение запроса с оператором INNER JOINafter у FROMменя не сработало. Мне не удалось выполнить запрос, потому что программа пожаловалась на FROMоператор.

Итак, чтобы запрос работал, я изменил его на

UPDATE table1 INNER JOIN table2 on table1.column1 = table2.column1
SET table1.column2 = table2.column4
WHERE table1.column3 = 'randomCondition';

вместо того

UPDATE a
FROM table1 a INNER JOIN table2 b on a.column1 = b.column1
SET a.column2 = b.column4
WHERE a.column3 = 'randomCondition';

Думаю, мое решение - правильный синтаксис MySQL.

AxeEffect
источник
Да, похоже, что для Mysql JOIN считается частью запроса table_references. MySQL Join
AWP
12
UPDATE
    "QuestionTrackings"
SET
    "QuestionID" = (SELECT "QuestionID" FROM "Answers" WHERE "AnswerID"="QuestionTrackings"."AnswerID")
WHERE
    "QuestionID" is NULL
AND ...
Милен А. Радев
источник
1
У меня работал над оракулом. Ответ @ eglasius - нет.
Ломбас
7

У меня был тот же вопрос. Вот рабочее решение, похожее на решение eglasius. Я использую postgresql.

UPDATE QuestionTrackings
SET QuestionID = a.QuestionID
FROM QuestionTrackings q, QuestionAnswers a
WHERE q.QuestionID IS NULL

Он жалуется, если q был использован вместо имени таблицы в строке 1, и ничего не должно предшествовать QuestionID в строке 2.

Освещение умы
источник
3
 select p.post_title,m.meta_value sale_price ,n.meta_value   regular_price
    from  wp_postmeta m 
    inner join wp_postmeta n
      on m.post_id  = n.post_id
    inner join wp_posts p
      ON m.post_id=p.id 
    and m.meta_key = '_sale_price'
    and  n.meta_key = '_regular_price'
     AND p.post_type = 'product';



 update  wp_postmeta m 
inner join wp_postmeta n
  on m.post_id  = n.post_id
inner join wp_posts p
  ON m.post_id=p.id 
and m.meta_key = '_sale_price'
and  n.meta_key = '_regular_price'
 AND p.post_type = 'product'
 set m.meta_value = n.meta_value;
Фрэнк
источник
3

Для Mysql вы можете использовать этот запрос

ОБНОВИТЬ table1 a, table2 b SET a.coloumn = b.coloumn ГДЕ a.id = b.id

Самир Патель
источник
1

Обновить данные второй таблицы в 1-й таблице необходимо для внутреннего соединения перед SET:

`UPDATE `table1` INNER JOIN `table2` ON `table2`.`id`=`table1`.`id` SET `table1`.`name`=`table2`.`name`, `table1`.`template`=`table2`.`template`;
Сантош Сингх
источник
1

ниже работает для mysql

update table1 INNER JOIN table2 on table1.col1 =  table2.col1
set table1.col1 =  table2.col2
Pravin
источник
0

Я думаю, это должно сработать.

UPDATE QuestionTrackings
SET QuestionID = (SELECT QuestionID
                  FROM AnswerTrackings
                  WHERE AnswerTrackings.AnswerID = QuestionTrackings.AnswerID)
WHERE QuestionID IS NULL
AND AnswerID IS NOT NULL;
Новичек
источник