2011-07-08 22 views
8

私はmysqlの2行のIDをPHPで切り替えようとしています。矛盾する情報がたくさんあるようです。誰かが決定的な答えを得ていますか?MySqlの2行のスイッチID番号

例えば、初期状態では、私の行は

1-Peter-22-germany 
2-mary-16-iceland 
3-tom-29-france 
4-michael-34-greece 

であり、もし私ように、それはこの

1-Peter-22-germany 
3-mary-16-iceland 
2-tom-29-france 
4-michael-34-greece 

ようになりますように、私は、行2と3のIDを交換したいと思います私が持っていただろうとIDで注文した

1-Peter-22-germany 
2-tom-29-france 
3-mary-16-iceland 
4-michael-34-greece 
+0

@amosriveraありがとう私はちょうどそれをやろうとしていました - ごめんなさい – byronyasgur

+1

あなたは実際にIDを変更したいのですか、時々別の順序でそれを取得したいですか? –

+0

@byronyasgur no prob、ちょうどテキストを選択して、コードフォーマット – amosrivera

答えて

11

IDが主キーの場合は、変更したり変更したりする必要はありません。これはソートのためだけの場合は、整数で並べ替える「注文」列を作成することをお勧めします。これについてはテーブルスキーマがうれしいですが、これはこれまでの私の推奨事項です。

行が入力されたときにIDが自動的に作成された場合、この考えはさらに大きな問題です。しかし、今私はあなたのテーブルのスキーマを知らないので推測しています。

ここにプライマリキーに関する標準的なアドバイスがあります:一意の識別子以外のものとは考えないでください。

+0

私は個々の要素の順序を変更したいというリストを持っています - それはソートではありません - テーブルを操作して永久的な変更ができるようにしたい – byronyasgur

+0

IDを変更したい理由は何ですか?なぜ私はあなたがこれを達成したいのか理解していないと思う。 – Brian

+0

テーブルが永久に表示される順序を変更したいのですが、ORDER BYの日付に設定されていて、日付のうちの1つを変更したようです.... ID以外のものは....私は別のものを持つことができると思います列にソート順が含まれていて、IDの代わりにその値が変更される – byronyasgur

0

あなたはSORT BYが必要です。私たちはあなたのテーブルスキーマを見る必要があります。

+0

いいえ、 - 私はそれを永久に変更したい – byronyasgur

+3

@byronyasgur:あなたがそれらを並べ替えるまで、テーブルには固有の順序がありません。行は、任意の順序で問合せから出る可能性があります。 – duskwuff

+1

@duskwuff "あなたが並べ替えるまで、テーブルには固有の順序がありません。"私はそれが好きです、それは非常に真実です。 – Brian

11
UPDATE yourtable SET id=IF(id=2, 3, 2) where id in(2,3) 

トリックを行う可能性がありますが、これは悪い考えている - /主キーの値を再割り当てすることは良いアイデア操作することはありません。

重複したキー違反(ほとんどの場合)が原因で失敗した場合、そのIDの1つを他の完全な値に一時的に再割り当てして、再割り当て中に競合しないようにする必要があります進行中です - 少なくとも2つのクエリを使用する必要があります。

+0

プライマリキー値の操作/再割り当ては決して良い考えではありません。 - 最終的にそれはリスト(仕事リスト/買い物リストなど)であり、リストの順序を変更できる必要があります(アルファベット順やORDERBYのようなものを注文するのではなく....私は定期的にできる必要がありますそれの順序を変更してください)....あなたに何をアドバイスしますか – byronyasgur

+1

ソートに使用できる2番目の整数フィールドを追加してください。あなたが望む限り、そのフィールドを変更することには害はありません。一次キーは一度割り当てられたままにしておく必要があります。特に、外部キーに使用する場合 –

1

なぜあなたはそれが永続的である必要があるのか​​が分かりません。私が考えることができるのは唯一のものなので、イベントの見かけの順序を変えることができます。

他にも述べたように、IDは通常主キーと自動番号付きであるため難しくなりますが、これを実現する明白な方法は、2つの項目のすべてのフィールドデータを配列に集め、他のものからのVALUES比較的容易

+0

ありがとう - 私は本当に私は別の列 "sortorder"を持っていて、それを変更する必要があったときに私はidを変更することを求めていたと思う...私はリストパンミルクフィッシュを持っていたと私はパンミルクの牛乳に変更し、そのように....その列(sortorderなど)で並べ替えるたびに、最後に残った方法で表示されるようになります....それを基にして、リストを並べ替えることができます。 – byronyasgur

+0

ええ、別の列は行く方法です。私はあなたがそれがあなたが望んでいたものではないとコメントしているのを見たと思った – horatio

0

スワップIDは、ストアドプロシージャとtempoparyテーブルで実装する:

CREATE PROCEDURE `swapIDs`(aTable varchar(64),aID1 int(11),aID2 int(11)) 
BEGIN 
drop temporary table if exists swapIDsTable; 
SET @s = concat('create temporary table swapIDsTable like ',aTable); PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt; 
SET @s = concat('insert into swapIDsTable select * from ',aTable,' where id=',aID1); PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt; 
SET @s = concat('delete from ', aTable, ' where id=',aID1); PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt; 
SET @s = concat('update ', aTable, ' set id=',aID1,' where id=',aID2); PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt; 
SET @s = concat('update swapIDsTable set id=',aID2,' where id=',aID1); PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt; 
SET @s = concat('insert into ', aTable,' select * from swapIDsTable where id=',aID2); PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt; 
drop temporary table if exists swapIDsTable; 
END | 

しかし、(アプリケーション)側と唯一の手掛かり(アプリケーションのクライアント上の別のユーザーによって更新され、あなたがswapedてきたIDを想像します更新するrawがIDであることを理解する。それは悪夢だろう。

この手順は、1人のユーザーの使用で100%有効です。

もう一つの方法は、2つの列の間のすべての列の値を(交換)を更新することです:あり

UPDATE targetTable tab1, targetTable tab2 SET tab1.<colX>=tab2.<colX>, tab2.<colX>=tab1.<colX> where tab1.id=<id1> and tab2.id=<id2>; 

まだいくつかの同期メカニズムであることが必要です。

+0

1つの行を削除してから再度挿入することをお勧めします。これはプライマリキーなので、それを参照する外部キーがあると失敗しませんか?あるいは、(CASCADE DELETE'アクションが定義されている場合)他のテーブルの行を削除して(100万以上)行を削除しますか? –

+0

はい、外部キーとCASCADE DELETEは、ストアドプロシージャ/一時テーブルの場合に問題になります。しかし、私は最初の質問でそれを見ていない:) – Jecksom