2012-04-09 3 views
3

私は研究しており、私は独特の状況があることを認識しています。SQL - 削除後に順次列が連続して番号が付け直される

まず第一に、私は列(常にではない識別子列)が複数のテーブルを持って、私は新しいユーザですので、ボードにはまだ画像を投稿することができ、とても

以下の適切なリンクが表示されないのです番号が付いていてはいけません。私の目標は、これが真実であることを確認することです。

ダウンとダーティー 「イベント」テーブルがランダムに選択され、「結果」テーブルに挿入されます。 「結果」の「ID」列は一連の削除クエリに渡されます。

多かれ少なかれ、複数のテーブルに行がないことを保証します。

私の問題: 私が指定した列の番号を変更するSQLクエリを解き明かします。私は列を落とさないことを好む。あなたは2行から削除された見ることができるように

enter image description here

:後

enter image description here

例表:

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

例テーブル前:

例は、クエリを削除します両方のテーブルID列に基づいています。今度は、item_ticket_idとitem_void_id列の番号をつけ直す方法を考えなければなりません。高い方の数字が欠損値に減少し、次に高い方が減少するなどです。問題#2、item_ticket_idがItemTickets ItemVoidのitem_ticket_idの変更を更新する必要があります。

私はあなたにこれに与えることができる任意のアドバイスをいただきありがとうございます。

+7

IMOこれは設計上の欠陥のようですが、行を削除する代わりにビットフラグを使用して非アクティブとしてマークし、クエリから除外します。次に、削除ごとにレコードの番号を変更する必要はありません。 – Taryn

答えて

3

あなたはこれに関する助言を探しているので、あなたのデザインに大きな欠陥があるので、これを再設計する必要があります。

レコードを削除して残りのレコードの番号を変更するのではなく、bitフラグを使用して、レコードをInactiveとマークします。

SELECT * 
FROM yourTable 
WHERE Inactive = 0 

が続いてレコードを再番号付けを心配する必要はありません:あなたは、レコードを照会している場合にのみ、レコードがアクティブであることですが含まに続いて、ちょうどWHERE句が含まれます。これにより、削除されたレコードを見て回って履歴を失うこともありません。

本当にレコードを削除してから、このタスクに次のような方法を実行することができ、それらを付け直すにしたい場合:

  1. 新しい番号を使用して、新しいテーブルに元のデータを挿入し
  2. 新しいテーブルを作成します
  3. 修正番号

Aを使用して新しいテーブルの名前を変更

  • 古いテーブルをドロップレコードの番号付けを変更する際には、多くのステップが必要になることがわかります。ビットフラッグのUPDATEを実行するだけで、このように多くの作業を作成できます。

    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フラグがはるかに簡単であり、それは私が推薦する方法で次のようになります。

    あなたはこれに似たものに、あなたのDELETEクエリを変更します。

  • 2

    あなたが探している機能はウィンドウ機能です。標準SQL(SQL Server、MySQL)では、関数はrow_number()です。次のようにあなたはそれを使用する:

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

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

    Oracleは同様の機能をサポートしていますが、構文は少し異なります。 Oracleは、これらのファンクション分析ファンクションをコールし、より豊富なオペレーションをサポートします。

    カーソルは、パフォーマンスが悪いため、使用することを強くお勧めします。もちろん、この列は変更できないため、ID列では機能しません。

    +0

    こんにちはゴードンさん、WITHコマンドを使った例がありますか?あなたは私の仕事をする必要はありません。一般的な例が必要です。最後の手段としてオプション2は、新しいID番号が新しいデータ行にあるかどうかにかかわらず、行の番号を簡単に変更して順次番号付けを確実にすることです。 – user1322659

    11

    (私はこれを探していたとき、それは最初の検索結果ですと古い質問に答える)
    (MS T-SQL)

    ID列(ないアイデンティティ1)を再順序付けするために、その新しいシーケンスを生成するためにrow_number()の単純なCTEのみを使用して を実行することができます。 UPDATEはCTEの「仮想テーブル」を介して問題なく動作し、実際に元の元のテーブルを更新します。
    IDフィールドが既に設定されているときに何が起こるのだろうと、更新中にIDフィールドがぶつかる心配はありません。 はその問題を抱えません。元のシーケンスは新しいシーケンスに変更されます。

    WITH NewSequence AS 
    (
        SELECT 
        ID, 
        ROW_NUMBER() OVER (ORDER BY ID) as ID_New 
        FROM YourTable 
    ) 
    UPDATE NewSequence SET ID = ID_New; 
    
    +0

    これはうまくいくようです –

    +0

    恐ろしいです!これらのクエリを使用する場合は、テーブルの特定の行にのみ影響を与えるWHEREを追加することを忘れないでください。 – JC203

    関連する問題