5

私は調査し、私には独特の状況があることに気付きました。

まず、私は新しいユーザーであるため、ボードに画像を投稿することはまだ許可されていません。以下の適切なリンクを参照してください。

列 (常に識別子列ではない) に連続番号が付けられ、番号付けに切れ目があってはならない複数のテーブルがあります。私の目標は、これが真実であることを確認することです。

Down and Dirty 行のパーセンテージをランダムに選択し、その行を「結果」テーブルに挿入する「イベント」テーブルがあります。「結果」の「ID」列は、一連の削除クエリに渡されます。

これにより、多かれ少なかれ、いくつかのテーブルで行が欠落していることが保証されます。

私の問題:指定した列の番号を付け直すSQLクエリを見つけます。列を削除しないことを好みます。

削除クエリの例:

delete ItemVoid
from ItemTicket
join ItemVoid
on ItemTicket.item_ticket_id = itemvoid.item_ticket_id
where itemticket.ID in (select ID
            from results)

前のテーブルの例:

ここに画像の説明を入力

後の表の例:

ここに画像の説明を入力

ご覧のとおり、ID 列に基づいて両方のテーブルから 2 行が削除されました。そこで、item_ticket_id 列と item_void_id 列の番号を付け直す方法を理解する必要があります。ここでは、大きい方の数値が欠損値に減少し、次に大きい数値が減少します。 、次に ItemVoid の item_ticket_id でその変更を更新する必要があります。

これについてアドバイスをいただければ幸いです。

4

3 に答える 3

15

(これを調べたときの最初の検索結果であるため、古い質問に答えます)
(MS T-SQL)

ギャップのある ID 列 (Identity 列ではない) を再row_number()シーケンスするには、新しいシーケンスを生成する単純な CTE のみを使用して実行できます。CTE 「UPDATE仮想テーブル」を介して問題なく機能し、実際に基になる元のテーブルを更新します。
更新中に ID フィールドが衝突することを心配する必要はありません。ID が既に存在するように設定されているとどうなるか疑問に思っている場合でも、その問題は発生しません。元のシーケンスは一度に新しいシーケンスに変更されます。

WITH NewSequence AS
(
  SELECT
    ID, 
    ROW_NUMBER() OVER (ORDER BY ID) as ID_New
  FROM YourTable
)
UPDATE NewSequence  SET ID = ID_New;
于 2014-04-02T09:02:16.927 に答える
3

あなたはこれについてアドバイスを求めているので、私のアドバイスは、あなたのデザインに大きな欠陥があるので、これを再デザインする必要があるということです.

レコードを削除してから、残りのレコードの番号を付け直す手間をかける代わりにbit、レコードを としてマークするフラグを使用しInactiveます。次に、レコードをクエリするときに、WHEREアクティブなレコードのみを含める句を含めます。

SELECT *
FROM yourTable
WHERE Inactive = 0

その後、レコードの再番号付けについて心配する必要はありません。これにより、削除されたはずのレコードを遡って確認することもでき、履歴を失うことはありません。

本当にレコードを削除して番号を付け直したい場合は、次の方法でこのタスクを実行できます。

  1. 新しいテーブルを作成する
  2. 新しい数値を使用して元のデータを新しいテーブルに挿入します
  3. 古いテーブルをドロップ
  4. 新しいテーブルの名前を修正した番号に変更します

ご覧のとおり、レコードの再番号付けには多くの手順が必要です。UPDATEビットフラグを 実行するだけで、この方法でより多くの作業を作成できます。

DELETEクエリを次のように変更します。

UPDATE ItemVoid
SET InActive = 1
FROM ItemVoid
JOIN ItemTicket
    on ItemVoid.item_ticket_id = ItemTicket.item_ticket_id
WHERE ItemTicket.ID IN (select ID from results)

フラグのbit方がはるかに簡単で、私が推奨する方法です。

于 2012-04-09T21:27:33.190 に答える
2

探している関数はウィンドウ関数です。標準 SQL (SQL Server、MySQL) では、関数は row_number() です。次のように使用します。

select row_number() over (partition by <col>)
from <table>

あなたのケースでこれを使用するには、テーブルから行を削除し、with ステートメントを使用して行番号を再計算し、更新を使用してそれらを割り当てます。トランザクションの整合性のために、削除と更新を 1 つのトランザクションにラップできます。

Oracle も同様の機能をサポートしていますが、構文が少し異なります。Oracle はこれらの関数を分析関数と呼び、より豊富な操作セットをサポートしています。

カーソルはパフォーマンスが悪いため、カーソルを使用しないように強く注意してください。もちろん、これは ID 列では機能しません。そのような列は変更できないからです。

于 2012-04-09T21:34:13.637 に答える