Può l'ordinamento da un'istruzione ORDER BY essere salvato in modo esplicito con una sola istruzione UPDATE?

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

  •  16-10-2019
  •  | 
  •  

Domanda

Ho questa tabella:

SELECT * FROM items

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

Ordinamento questa tabella dà questo risultato:

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

Ora voglio aggiornare la tabella e salvare l'ordine nella colonna di posizione:

SELECT * FROM items

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

Può questo essere fatto con una singola query o devo ciclo manualmente su tutte le righe e fare un aggiornamento manuale?

Nel caso l'ordine non completamente definito (ad esempio per il cavo USB e tastiera sopra) ho arbitrariamente deciso l'ordine.

È stato utile?

Soluzione

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: l'ordine di "tastiera" e "cavo USB" è arbitraria. Entrambi hanno posizione = 0

Per legare-break posizioni basate su articolo, una sorta secondario

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

Se si dispone di posizione duplicato, coppie elemento questo sarà arbitrario troppo ...

Altri suggerimenti

Ecco come raggiungere questo obiettivo in 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;

Ho usato i dati di esempio dalla questione, caricato in MySQL 5.5.15 sul mio portatile, e sono corso quelle due righe. Ecco il risultato:

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)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a dba.stackexchange
scroll top