2016年3月22日火曜日

CASE式を使用して、主キーを入れ替える方法 SQL

こんにちは山田です。

気温もぐーんとあがり、
やっと春らしくなってきました。今日この頃。

さて、SQLの話題です。既存コードをリファクターできそうなものを見つけたので、その備忘録になります。

■目的
「主キー」もしくは「ユニークキー」の値を入れ替えて、
並び替え機能をつくります。

■テーブルの前提
 1. ソートキーはユニークである
 2. ソートキーが大きいものが上(降順)で並べる

表であらわすと↓こんな感じになります。
+-----+------------+--------+
| ID  | Name       | Sorter |
+------------------+--------+
| 1   | ゼンサイ      | 100    |
| 2   | メインリョウリ    | 10     |
| 3   | スープ       | 1      |
+-----+------------+--------+
このソートキー「100」と「10」を入れ替えて登録して、並び替え機能をつくります
         ↓
+-----+------------+--------+
| ID  | Name       | Sorter |
+------------------+--------+
| 2   | メインリョウリ    | 100    |
| 1   | ゼンサイ      | 10     |
| 3   | スープ       | 1      |
+-----+------------+--------+
                ※IDとNameは対応しています。

■仮数字を一時的に代入する方法(元々の方法)
update mst_data
   set Sorter = '-1'
  where where ID = '1'  /*ID「1」のSoterを一時的に「-1」を代入*/
update mst_data
   set Sorter = '100'
  where where ID = '2' /*ID「2」のSorterに、空いた「100」を代入*/
update mst_data
   set Sorter = '10'
  where where ID = '1' /*ID「1」のSorterに目的の「10」を代入*/
この3つのクエリ文でトランザクションを作ってやっていました。
動作するものの、以下の懸念点がありました。
 ・クエリ文が3つできてしまう
 ・仮数字がすでに使われていた場合、ユニーク制約のため、-1が代入できなくなる


この解決方法として、CASE式を使用した方法をとります。

■CASE式を使って、ユニークキーを入れ替える方法
update mst_data
 set sorter = CASE WHEN sorter = '100' THEN '10'
                WHEN sorter = '10'  THEN '100'
               ELSE sorter END
 where sorter in( '100' , '10');
CASE式を使用することによって、一度のUPDATE文で入れ替えが完了できてしまいました。
どうしてこんなことが出来てしまうかというと、
CASE式の分岐による更新は「一気」におこなわれるので、
ユニークキーの重複エラーを回避することができるのです。


実はこの方法、主キーを入れ替えるという荒業も簡単にできてしまいます。
■CASE式を使って、主キーを入れ替える方法

操作対応表 
・SQL Server: ○
・Oracle  : ○
・MySQL  : ×
update mst_data
 set sorter = CASE WHEN id = '1' THEN '2'
                WHEN id = '2' THEN '1'
               ELSE id END
 where sorter in( '1' , '2');
その場合の実行結果
+-----+------------+--------+
| ID  | Name       | Sorter |
+------------------+--------+
| 1   | ゼンサイ      | 100    |
| 2   | メインリョウリ    | 10     |
| 3   | スープ       | 1      |
+-----+------------+--------+

+-----+------------+--------+
| ID  | Name       | Sorter |
+------------------+--------+
| 2   | ゼンサイ      | 100    |
| 1   | メインリョウリ    | 10     |
| 3   | スープ       | 1      |
+-----+------------+--------+

■参考サイト
『達人に学ぶ SQL徹底指南書』サポートページ
http://www.geocities.jp/mickindex/database/db_support_sinan.html

Related Posts:

  • CASE式を使用して、主キーを入れ替える方法 SQLこんにちは山田です。 気温もぐーんとあがり、 やっと春らしくなってきました。今日この頃。 さて、SQLの話題です。既存コードをリファクターできそうなものを見つけたので、その備忘録になります。 ■目的 「主キー」もしくは「ユニークキー」の値を入れ替えて、 並び替え機能をつくります。 ■テーブル… Read More
  • datetimeの列でデータを抽出したい!岡田です。 データを抽出するときってだいたい数値か文字列で検索を書けるのですが、今回あまりなじみのないdatetime型の列で抽出しなくてはいけない作業があったので、メモしておきます。 例えばその日時が2000年12月31日だった場合は、、、 select top 100 * from d… Read More
  • 開発初心者がこれだけは知っておいた方が良いこと④こんにちは!Sです。 今回はデータベースのロックについて書きたいと思います。 DBで行う主な操作としては ①新規登録 ②更新 ③削除 ④参照 だと思いますが、同じテーブルに対して複数の人が同時に様々な操作を行うとデータの整合性がとれません。 そんなことにならないようにDBにはロックという機能が… Read More
  • 【SQLserver】DBテーブル内のカラムにコメントを登録するこんにちわ、開発者のⅠです。 さて、今回はDB操作に関するお話です。 クエリ文を作成しそれをプログラム上で実行することで、新規テーブルの作成やカラム追加など、様々な操作が可能です。 その中で、今回はカラムにコメントを登録する方法を伝えします。 カラムの定義変更や追加には【ALTER TABLE】… Read More

0 コメント:

コメントを投稿