0

属性のグループを格納し、それらを順番に並べたテーブルがあります。属性 (行) の 1 つがテーブルから削除される可能性があり、一連の位置を圧縮する必要があります。

たとえば、最初にこれらの値のセットがある場合:

+----+--------+-----+
| id | name   | pos |
+----+--------+-----+
|  1 | one    |   1 |
|  2 | two    |   2 |
|  3 | three  |   3 |
|  4 | four   |   4 |
+----+--------+-----+

2 番目の行が削除されたので、後続のすべての行の位置を更新してギャップを埋める必要があります。結果は次のようになります。

+----+--------+-----+
| id | name   | pos |
+----+--------+-----+
|  1 | one    |   1 |
|  3 | three  |   2 |
|  4 | four   |   3 |
+----+--------+-----+

単一のクエリでこの更新を行う方法はありますか? どうすればこれを行うことができますか?

PS: システムは両方のエンジンをサポートするはずなので、SQLServer と Oracle の両方の例を教えていただければ幸いです。ありがとう!

更新:これは、ユーザーが自由に位置を変更したり、新しい行を追加または削除したりできるためです。位置はユーザーに表示されます。そのため、これらは常に一貫したシーケンスを表示する必要があります (このシーケンスは保存する必要があり、オンデマンドで生成することはできません)。

4

3 に答える 3

4

それが機能するかどうかはわかりませんが、Oracleでは次のことを試します:

update my_table set pos = rownum;
于 2011-02-01T13:08:11.550 に答える
0

これは機能しますが、大規模なデータセットには最適ではない可能性があります。

SQL> UPDATE my_table t
  2     SET pos = (SELECT COUNT(*) FROM my_table WHERE id <= t.id);

3 rows updated

SQL> select * from my_table;

        ID NAME              POS
---------- ---------- ----------
         1 one                 1
         3 three               2
         4 four                3
于 2011-02-01T13:52:24.957 に答える
0

シーケンス値が連続していることが本当に必要ですか、それとも連続した値を表示できるようにする必要があるだけですか? これを行う最も簡単な方法は、実際のシーケンスをまばらにして、順序に基づいてランクを計算することです。

select id, 
       name, 
       dense_rank() over (order by pos) as pos,
       pos as sparse_pos 
from my_table

(注: これは Oracle 固有のクエリです)

最初に位置をまばらにすると、2 つの既存の位置の中間に新しい位置を作成できるため、並べ替えがさらに簡単になります。たとえば、次のようなテーブルがあるとします。

+----+--------+-----+
| id | name   | pos |
+----+--------+-----+
|  1 | one    | 100 |
|  2 | two    | 200 |
|  3 | three  | 300 |
|  4 | four   | 400 |
+----+--------+-----+

ID 4 を位置 2 に移動するときが来たら、位置を 150 に変更します。


さらなる説明:

上記の例を使用すると、ユーザーには最初に次のように表示されます (位置をマスクしているため)。

+----+--------+-----+
| id | name   | pos |
+----+--------+-----+
|  1 | one    |   1 |
|  2 | two    |   2 |
|  3 | three  |   3 |
|  4 | four   |   4 |
+----+--------+-----+

ユーザーがインターフェースを通じて、位置 4 のレコードを位置 2 に移動する必要があることを示した場合、ID 4 の位置を 150 に更新してから、クエリを再実行します。ユーザーには次のように表示されます。

+----+--------+-----+
| id | name   | pos |
+----+--------+-----+
|  1 | one    |   1 |
|  4 | four   |   2 |
|  2 | two    |   3 |
|  3 | three  |   4 |
+----+--------+-----+

これが機能しない唯一の理由は、ユーザーがデータベースで直接データを編集している場合です。ただし、その場合でも、ビューとトリガーの代わりに、この種のソリューションを使用する傾向があります。

于 2011-02-01T14:55:13.283 に答える