题
我有这个表:
SELECT * FROM items
id | item | position
---|-----------|----------
1 | USB cable | 0
2 | SD card | 4
3 | Mouse | 2
4 | Keyboard | 0
5 | Monitor | 3
对此表进行排序给出了此结果:
SELECT * FROM items ORDER BY position
id | item | position
---|-----------|----------
4 | Keyboard | 0
1 | USB cable | 0
3 | Mouse | 2
5 | Monitor | 3
2 | SD card | 4
现在,我想更新表并将订单保存在位置列中:
SELECT * FROM items
id | item | position
---|-----------|----------
4 | Keyboard | 1
1 | USB cable | 2
3 | Mouse | 3
5 | Monitor | 4
2 | SD card | 5
可以通过一个查询来完成,还是我必须在所有行上手动循环并进行手动更新?
如果订单未完全定义(例如,上面的USB电缆和键盘),我只是任意决定订单。
解决方案
UPDATE
T1
SET
position = T2.rn
FROM
myTable T1
JOIN
(
SELECT
id,
ROW_NUMBER() OVER (ORDER BY position) AS rn
FROM
myTable
) T2 ON T1.id = T2.id
注意:“键盘”和“ USB电缆”的顺序是任意的。他们都有位置= 0
要根据项目打破抢断职位,请添加次要排序
ROW_NUMBER() OVER (ORDER BY position, item) AS rn
如果您有重复的位置,项目对也将是任意的...
其他提示
这是在MySQL中实现这一目标的方法:
set @x = 0;
update items A
inner join
(
select @x:=@x+1 newposition,id
from items
order by position
) B using (id)
set A.position=B.newposition;
我从问题上使用了您的示例数据,将其加载到笔记本电脑上的MySQL 5.5.15中,然后运行了这两行。这是结果:
mysql> use test
Database changed
mysql> drop table if exists items;
Query OK, 0 rows affected (0.01 sec)
mysql> create table items
-> (
-> id int not null auto_increment,
-> item varchar(20),
-> position int,
-> primary key(id)
-> );
Query OK, 0 rows affected (0.01 sec)
mysql> insert into items (item,position) values
-> ('USB cable',0),('SD Card',4),
-> ('Mouse',2),('Keyboard',0),('Monitor',3);
Query OK, 5 rows affected (0.00 sec)
Records: 5 Duplicates: 0 Warnings: 0
mysql> select * from items;
+----+-----------+----------+
| id | item | position |
+----+-----------+----------+
| 1 | USB cable | 0 |
| 2 | SD Card | 4 |
| 3 | Mouse | 2 |
| 4 | Keyboard | 0 |
| 5 | Monitor | 3 |
+----+-----------+----------+
5 rows in set (0.00 sec)
mysql> select * from items order by position;
+----+-----------+----------+
| id | item | position |
+----+-----------+----------+
| 1 | USB cable | 0 |
| 4 | Keyboard | 0 |
| 3 | Mouse | 2 |
| 5 | Monitor | 3 |
| 2 | SD Card | 4 |
+----+-----------+----------+
5 rows in set (0.00 sec)
mysql> set @x = 0;
Query OK, 0 rows affected (0.00 sec)
mysql> update items A
-> inner join
-> (
-> select @x:=@x+1 newposition,id
-> from items
-> order by position
-> ) B using (id)
-> set A.position=B.newposition;
Query OK, 5 rows affected (0.00 sec)
Rows matched: 5 Changed: 5 Warnings: 0
mysql> select * from items;
+----+-----------+----------+
| id | item | position |
+----+-----------+----------+
| 1 | USB cable | 1 |
| 2 | SD Card | 5 |
| 3 | Mouse | 3 |
| 4 | Keyboard | 2 |
| 5 | Monitor | 4 |
+----+-----------+----------+
5 rows in set (0.00 sec)
mysql> select * from items order by position;
+----+-----------+----------+
| id | item | position |
+----+-----------+----------+
| 1 | USB cable | 1 |
| 4 | Keyboard | 2 |
| 3 | Mouse | 3 |
| 5 | Monitor | 4 |
| 2 | SD Card | 5 |
+----+-----------+----------+
5 rows in set (0.00 sec)
不隶属于 dba.stackexchange