简体   繁体   中英

Trying to update a table related to multiple other rows in the same table

I have a table which represents a tree using nested sets with the typical left and right columns (trLeft and trRight). For optimization, I also include the row's level in the tree, which is the number of parents it has up to the tree ROOT.

In nested sets the Parents of a row A are all other rows B where B.trLeft < A.trLeft AND B.trRight > A.trRight .

So counting those rows will return the level, resulting in the following update query for a start in order to update all rows with the correct level:

UPDATE Groups AS g1 SET g1.trLevel = ( 
    SELECT COUNT(*) FROM Groups AS g2 WHERE g2.trLeft < g1.trLeft AND g2.trRight > g1.trRight ) ;

but this results in Error 1093 "You can't specify target table 'g1' for update in FROM clause.

Is there a way to get around this ?

A silly workaround is to nest a derived table inside a subquery, like so:

UPDATE Groups AS g1 
SET g1.trLevel = (
  SELECT COUNT(*) 
  FROM ( 
    SELECT *
    FROM Groups AS g2 
  ) AS temp
  WHERE 
    temp.trLeft < g1.trLeft 
    AND temp.trRight > g1.trRight 
);

I tested this by first building the table like so:

CREATE TABLE Groups (trLeft int, trRight int, trLevel int);

INSERT INTO Groups (trLeft, trRight) VALUES (1, 4), (5, 6), (2, 3);

and it works.

You have to sort of nest the count in a select. I think this will work:

EDITED: Updated query

UPDATE Groups SET trLevel = (
    SELECT * FROM 
    (
        SELECT COUNT(*) FROM Groups g2 inner join Groups g1 on g2.unique_id = g1.unique_id WHERE g2.trLeft < g1.trLeft AND g2.trRight > g1.trRight 
    ) AS my_count
) ;

The AS my_count is important because it tells MySQL to create a tmp table from this query. The my_count tmp table is then used as the source for the UPDATE statement.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM