¿Puede la clasificación de una instrucción ORDER BY se guardará de forma explícita con una sola instrucción UPDATE?

dba.stackexchange https://dba.stackexchange.com/questions/5146

  •  16-10-2019
  •  | 
  •  

Pregunta

Tengo esta tabla:

SELECT * FROM items

id | item      | position
---|-----------|----------
 1 | USB cable |        0
 2 | SD card   |        4
 3 | Mouse     |        2
 4 | Keyboard  |        0
 5 | Monitor   |        3

Clasificar esta tabla da este resultado:

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

Ahora quiero actualizar la tabla y guardar el orden en la columna de la posición:

SELECT * FROM items

id | item      | position
---|-----------|----------
 4 | Keyboard  |        1
 1 | USB cable |        2
 3 | Mouse     |        3
 5 | Monitor   |        4
 2 | SD card   |        5

¿Es posible hacerlo con una sola consulta o tengo al bucle manualmente sobre todas las filas y hacer una actualización manual?

En caso de que el pedido no está totalmente definido (por ejemplo, para el cable USB y teclado arriba) acabo decidió arbitrariamente el orden.

¿Fue útil?

Solución

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

Nota: el orden de "teclado" y "cable USB" es arbitraria. Ambos tienen la posición = 0

Para tie-break posiciones basadas en articulo, una especie secundaria

      ROW_NUMBER() OVER (ORDER BY position, item) AS rn

Si usted tiene posición duplicado, pares partida Este será arbitraria también ...

Otros consejos

Aquí es cómo lograr esto en 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;

He utilizado los datos de la muestra de la pregunta, lo cargó en MySQL 5.5.15 en mi portátil, y corrí esas dos líneas. Aquí está el resultado:

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)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a dba.stackexchange
scroll top