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 ...


MySQL та Microsoft SQL Server кожен підтримують розширення до синтаксису SQL, щоб підтримувати оновлення для багатьох таблиць. Інші бренди ні. Ви не сказали, яку марку бази даних використовуєте.
Білл Карвін

Відповіді:


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 ідентифікатор асоційованого питання.


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 видає синтаксичну помилку на "ВІД"
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.


Так, схоже на 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
Працював над Oracle для мене. @ відповіді eglasius не відповів.
Ломба

7

У мене виникло те саме питання. Ось робоче рішення, подібне до eglasius. Я використовую postgresql.

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

Він скаржиться, якщо замість назви таблиці в рядку 1 було використано q, і нічого не повинно передувати 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 WHERE a.id = b.id


1

Оновити дані 2-ї таблиці в 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

0

Я думаю, що це має спрацювати.

UPDATE QuestionTrackings
SET QuestionID = (SELECT QuestionID
                  FROM AnswerTrackings
                  WHERE AnswerTrackings.AnswerID = QuestionTrackings.AnswerID)
WHERE QuestionID IS NULL
AND AnswerID IS NOT NULL;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.