【问题标题】:Change column value based on ORDER根据 ORDER 更改列值
【发布时间】:2017-09-08 11:48:48
【问题描述】:

我有这张桌子:

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

我想为“listId”按字母顺序排列item 列。所以最后应该是这样的:

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

如果我需要在同一张桌子上运行SELECT 以按字母顺序排列项目,我该如何UPDATE 桌子?

谢谢

PS:我这样做的原因是因为项目在表格中并且可以向上或向下拖动到新位置,但我希望用户能够按字母顺序对它们进行排序并重新执行如果他们愿意,可以订购

【问题讨论】:

  • 我不明白您为什么需要更新“位置”。仅按字母顺序对结果集进行排序还不够吗?
  • @Strawberry 位置很重要,因为允许用户手动重新排序项目
  • 那么它们就不会按字母顺序排序[:confused:]

标签: mysql


【解决方案1】:

这里有一个解决方案:

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

输出:

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

小提琴:http://www.sqlfiddle.com/#!9/24f51/2/1


编辑:要进行更新,您可以执行以下操作:

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 在这里有点坏)完整的小提琴:

SQL Fiddle

MySQL 5.6 架构设置

-- +----+--------+------+----------+
-- | 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
);

查询 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 |

【讨论】:

  • 谢谢,但是如何使用newPosition 值更新表格?
【解决方案2】:

RC。只是用更新查询打败了我。 主要区别是我在一个查询中而不是在两个查询中进行。 我在同样有效的交叉连接中设置了用户变量。

创建表格/插入数据。

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)
;

查询

用你自己的表名替换 foo..

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  

结果

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

查询

SELECT * FROM foo ORDER BY position ASC

结果

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

【讨论】:

    猜你喜欢
    • 2021-10-10
    • 1970-01-01
    • 1970-01-01
    • 2021-09-05
    • 2016-11-16
    • 2022-07-28
    • 1970-01-01
    • 2019-01-18
    • 2022-11-30
    相关资源
    最近更新 更多