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:
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.