简体   繁体   中英

Change column value based on ORDER

I have this table:

+----+--------+------+----------+
| id | listId | item | position |
+----+--------+------+----------+
|  4 |      2 | z234 |        1 |
|  5 |      2 | f324 |        2 |
|  2 |      2 | gt22 |        3 |
|  3 |      2 | aa11 |        4 |
|  1 |      2 | b321 |        5 |
+----+--------+------+----------+

I want to make the item column for that `listId´ ordered alphabetically. So in the end, it should look like this:

+----+--------+------+----------+
| id | listId | item | position |
+----+--------+------+----------+
|  3 |      2 | aa11 |        1 |
|  1 |      2 | b321 |        2 |
|  5 |      2 | f324 |        3 |
|  2 |      2 | gt22 |        4 |
|  4 |      2 | z234 |        5 |
+----+--------+------+----------+

How can I UPDATE the table if I need to run a SELECT on the same table to order the items alphabetically?

Thank you

PS: The reason I'm doing this is because the items are in a table and can be dragged up or down to a new position, but I want the user to be able to just order them alphabetically and re-do the order if they wish

Here a solution:

SET @newPosition = 0;
SELECT id, listId, item, position, (@newPosition:=@newPosition + 1) AS newPosition 
FROM foo
ORDER BY item;

output:

| id | listId | item | position | newPosition |
|----|--------|------|----------|-------------|
|  3 |      2 | aa11 |        4 |           1 |
|  1 |      2 | b321 |        5 |           2 |
|  5 |      2 | f324 |        2 |           3 |
|  2 |      2 | gt22 |        3 |           4 |
|  4 |      2 | Z234 |        1 |           5 |

Fiddle: http://www.sqlfiddle.com/#!9/24f51/2/1


EDIT: to do the update, you can do something like:

SET @newPosition = 0;

UPDATE foo SET position = (
  SELECT tmp.newPosition FROM (
    SELECT id,listId,item,position,(@newPosition:=@newPosition + 1) AS newPosition 
    FROM foo
    ORDER BY item
  ) AS tmp WHERE tmp.id = foo.id
);

(sqlfiddle is kind of broken here) Full fiddle:

SQL Fiddle

MySQL 5.6 Schema Setup :

-- +----+--------+------+----------+
-- | id | listId | item | position |
-- +----+--------+------+----------+
-- |  4 |      2 | z234 |        1 |
-- |  5 |      2 | f324 |        2 |
-- |  2 |      2 | gt22 |        3 |
-- |  3 |      2 | aa11 |        4 |
-- |  1 |      2 | b321 |        5 |
-- +----+--------+------+----------+
CREATE TABLE foo (
  id INT,
  listId INT,
  item VARCHAR(5),
  position INT
);
INSERT INTO foo VALUES
(4, 2, 'Z234', 1),
(5, 2, 'f324', 2),
(2, 2, 'gt22', 3),
(3, 2, 'aa11', 4),
(1, 2, 'b321', 5);

SET @newPosition = 0;

UPDATE foo SET position = (
  SELECT tmp.newPosition FROM (
    SELECT id,listId,item,position,(@newPosition:=@newPosition + 1) AS newPosition 
    FROM foo
    ORDER BY item
  ) AS tmp WHERE tmp.id = foo.id
);

Query 1 :

SELECT * FROM foo

Results :

| id | listId | item | position |
|----|--------|------|----------|
|  4 |      2 | Z234 |        5 |
|  5 |      2 | f324 |        3 |
|  2 |      2 | gt22 |        4 |
|  3 |      2 | aa11 |        1 |
|  1 |      2 | b321 |        2 |

RC. just beat me with the update query. The main difference is I do it in one query instead off two queries. I set the user variable within a cross join that also works.

Create table/insert data.

CREATE TABLE foo
    (`id` INT, `listId` INT, `item` VARCHAR(4), `position` INT)
;

INSERT INTO foo
    (`id`, `listId`, `item`, `position`)
VALUES
    (4, 2, 'z234', 1),
    (5, 2, 'f324', 2),
    (2, 2, 'gt22', 3),
    (3, 2, 'aa11', 4),
    (1, 2, 'b321', 5)
;

Query

Replace foo with your own table name..

UPDATE 
 foo 
INNER JOIN (
  SELECT
     id
   , (@newPosition:=@newPosition + 1) AS newPosition 
FROM
 foo
ORDER BY
  item ASC
)
 AS foo_table
CROSS JOIN (
 SELECT @newPosition := 0
) AS init_user_var 
SET 
 foo.position =  foo_table.newPosition
WHERE
  foo.id = foo_table.id  

Result

1 queries executed, 1 success, 0 errors, 0 warnings

Query: UPDATE foo INNER JOIN ( SELECT id , (@newPosition:=@newPosition + 1) AS newPosition FROM foo ORDER BY item ASC ) as foo_table CR...

5 row(s) affected

Query

SELECT * FROM foo ORDER BY position ASC

Result

    id  listId  item    position  
------  ------  ------  ----------
     3       2  aa11             1
     1       2  b321             2
     5       2  f324             3
     2       2  gt22             4
     4       2  z234             5

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