ステートメント別の注文からのソートは、1つの更新ステートメントのみで明示的に保存できますか?

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

  •  16-10-2019
  •  | 
  •  

質問

私はこのテーブルを持っています:

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

これを1回のクエリで実行できますか、それともすべての行に手動でループして手動の更新を行う必要がありますか?

順序が完全に定義されていない場合(上記の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にロードし、これらの2行を実行しました。これが結果です:

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)
ライセンス: CC-BY-SA帰属
所属していません dba.stackexchange
scroll top