Update a column using a select subquery to the sam

2019-07-23 13:47发布

问题:

Sample table below. I recently added the column 'is_last_child' and want to update it to have a value 1 if the row is the last child (or is not a parent). I had a query of

update node set is_last_child=1 where id not in (select parent_id from node);

I get the following error when I run it. "You can't specify target table 'node' for update in FROM clause". I've tried using a join, but I'm sure how exactly I can update only the rows that are not a parent. Any one have any ideas or have run into a similar situation?

id | parent_id | is_last_child
1  |    1      |      0
2  |    1      |      0   
3  |    1      |      0
4  |    2      |      0
5  |    4      |      0
6  |    1      |      0

Essentially I want to select ids 3, 5, and 6 and set the column is_last_child equal to 1. This isn't my schema and there are thousands of rows, but the table above is just to simplify things.

回答1:

You want UPDATE FROM:

UPDATE N1
SET N1.is_last_child = 1
FROM Node N1
LEFT OUTER JOIN Node N2
    ON N1.ID = N2.Parent_ID
WHERE N2.ID IS NULL

The left outer join is conceptually the same as using NOT IN only it's easier to read and you don't need a bunch of nested queries.



回答2:

Use another subquery since you can't update a table you are selecting from at the same time (in MySQL). But by building a temp table it works

update node 
set is_last_child=1 
where id not in 
(
  select * from 
  (
     select parent_id from node
  ) tmp
);


回答3:

While you can't update a table you are selecting from, I think you can update a table joined to itself:

UPDATE `node` AS n1 LEFT JOIN `node` AS n2 ON n1.id = n2.parent_id 
SET n1.is_last_child = 1
WHERE n2.id IS NULL
;