简体   繁体   中英

How to select same table in update statement with MySQL

In this table, there is a column called 'position'. This column counts up from 0. (First row has position 0, second has 1 etc.)

Now, if the row with position 4, moves up, I want to set the row above (row with position 3) to the current position. (So position 3 becomes position 4.)

So for example:

I have:

id = 12, position = 2
id = 11, position = 3
id = 9, position = 4
id = 8, position = 5

After the update I want:

id = 12, position = 2
id = 11, position = 4
id = 9, position = 3
id = 8, position = 5

I want to use the id of the row, to update the position.

This is what I've got, but it doesn't work on MySQL:

UPDATE message
SET position = position + 1
WHERE position = (SELECT position - 1 FROM message WHERE id = 11);

When I try to run it, it gives me this error: 'SQL Error(1093): You can't specify target table 'message' for update in FROM clause'.

How can I fix this?

EDIT - after UPDATE with sample data from OP:

I assume you know the ID (=11) and want the data to change as illustrated in your updated question... you need to update 2 rows to achieve that:

UPDATE message m SET
m.position = (CASE WHEN m.id = 11 THEN m.position + 1 ELSE m.position - 1 END)
WHERE m.id = 11 OR m.id =
(SELECT z.li FROM (SELECT MAX (l.id) li FROM message h INNER JOIN message l ON h.position = (l.position - 1) WHERE h.id = 11) z);

Add ORDER BY position DESC to the query to do it from the bottom up and avoid having the same position twice at the same time.

Edit: I posted this before the OP said what his error was - I just guessed.

By far the simplest solution here is just get the position in the parent code, and don't do in in MySQL.

Think we need to follow this through (I think I've understood the idea, but correct me if not):

Consider two rows:

Before row change

ID=10, Position=3
ID=11, Position=4

We move ID=11 up:

ID=10, Position=3
ID=11, Position=3

We need

ID=10, Position=4
ID=11, Position=3

Therefore the update should be:

UPDATE message
SET position = position + 1
WHERE position = (SELECT position FROM (select id, position from message) WHERE id = 11)
    and id<>11

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