SQL UPDATE SET哪一列等于另一列引用的相关表中的值?


112

我希望这是有道理的,让我详细说明一下:

每一行都有一个测验程序的跟踪数据表。

QuestionID和AnswerID(每个都有一个表)。因此,由于存在一个错误,有一堆QuestionID设置为NULL,但是相关AnswerID的QuestionID在Answers表中。

因此,假设QuestionID为NULL,AnswerID为500,如果我们进入Answers表并找到AnswerID 500,则会出现一列带有QuestionID的列,该列应为NULL值所在的位置。

因此,基本上,我想将每个NULL QuestionID设置为等于在跟踪表中AnswerID的Answer行(与正在写入的NULL QuestionID相同的行)的Answers表中找到的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 ... ?

不知道如何使它从匹配的AnswerID中将QuestionID分配给QuestionID ...


MySQL和Microsoft SQL Server均支持SQL语法扩展,以支持多表UPDATE。其他品牌则没有。您尚未说出正在使用什么品牌的数据库。
比尔·卡文

Answers:


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

特别是每个答案ID是否肯定只有1个相关问题ID。


7
我不确定为什么,但是这对我不起作用,但是这样做:update QuestionTrackings q inner join QuestionAnswers a on q.AnswerID = a.AnswerID set q.QuestionID = a.QuestionID; 似乎是相同的基本查询,但顺序不同。知道为什么吗?
billynoah 2014年

2
@ billynoah,ORA-00971:Oracle中缺少SET关键字
masT 2014年

2
通过MySQL在PhpMyAdmin中遇到类似情况的问题。在我的情况下,源列和目标列在同一张表中,但记录选择基于另一张表。查询的“ SELECT”版本有效,但是UPDTATE语句在“ FROM”上引发语法错误
2NinerRomeo

3
我通过消除“ FROM”解决了我的问题,它看起来像这样:UPDATE table1 NATURAL JOIN table2 SET table1.col1 = table1.col2 WHERE table2.col3 ="condition"
2NinerRomeo 2015年

答案中的“更新q”中的“ q”是文字查询参数,还是只是表名的简写?
肖恩

28

如果没有update-and-join符号(并非所有DBMS都支持),请使用:

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)

通常在这样的查询中,您需要使用包含子查询的EXISTS子句来限定WHERE子句。这样可以防止UPDATE踩到没有匹配项的行(通常使所有值都为空)。在这种情况下,由于缺少问题ID会将NULL更改为NULL,因此可以说这无关紧要。


该方法对我来说适用于Oracle 12c(其中update-join方法失败)。
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


7

我有同样的问题。这是一个类似于eglasius的工作解决方案。我正在使用postgresql。

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

它抱怨是否在第1行中使用q代替表名,并且在第2行中的QuestionID之前不应有任何内容。


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;


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;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.