2009-10-21 12 views
9

私はいくつかのレガシーコード/データベースで作業しており、その(外来)IDに関連するシーケンス番号を記録するフィールドをデータベースに追加する必要があります。テーブルデータ(現在)MySQL:別のフィールドに基づいてシーケンス列を追加します。

例:配列アカウントに関連していること

ID  ACCOUNT  SEQ  some_other_stuff 
1  1   1  ... 
2  1   2  ... 
3  1   3  ... 
4  2   1  ... 
5  2   2  ... 
6  1   4  ... 

注:

ID  ACCOUNT  some_other_stuff 
1  1   ... 
2  1   ... 
3  1   ... 
4  2   ... 
5  2   ... 
6  1   ... 

Iは達成、アカウントごとに別々にインクリメントsequenceid列を追加する必要があります。

SQLでこれを実現する方法はありますか、私の仕事をするPHPスクリプトに頼っていますか?

TIA、 ケヴ

答えて

6

これをおそらく遅いでしょう:

CREATE temporary table seq (id int, seq int); 
INSERT INTO seq (id, seq) 
    SELECT id, 
     (SELECT count(*) + 1 FROM test c 
     WHERE c.id < test.id AND c.account = test.account) as seq 
    FROM test; 

UPDATE test INNER join seq ON test.id = seq.id SET test.seq = seq.seq; 

私はテーブル 'test'を呼び出しました。明らかに正しく設定する必要があります。一時テーブルを使用する必要があります。これは、MySQLが、更新する同じテーブルの副選択を使用できないためです。

+0

@tom haigh canあなたはどういう仕組みか説明してください。 – FBP

4

は、問題はそうはい、MySQLのAUTO_INCREMENTは、GroupWiseのシーケンシャルなIDを作成することができ、 "mysqlの" としてタグ付けされます。
http://dev.mysql.com/doc/refman/5.0/en/example-auto-increment.htmlを参照してください。

のMyISAMBDBテーブルの場合は、複数のカラムインデックスで二列にAUTO_INCREMENTを指定することができます。この場合、AUTO_INCREMENT列の生成値は MAX(auto_increment_column) + 1 WHERE prefix=given-prefixと計算されます。これは、データを順序付けられたグループに入れたい場合に便利です。

編集:例のPHPスクリプト(PDOを使用して、それがphp-mysqlモジュールと同じゲームです)

$pdo = new PDO('mysql:host=...;dbname=...', '...', '...'); 
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 

// example table 
$pdo->exec(
    'CREATE TEMPORARY TABLE Foo (
    id int auto_increment, 
    account int, 
    someotherstuff varchar(32), 
    primary key(account,id) 
) engine=MyIsam' 
); 
// insert example data 
$stmt = $pdo->prepare('INSERT INTO Foo (account,someotherstuff) VALUES (?,?)'); 
$stmt->execute(array(1, '1a')); 
$stmt->execute(array(1, '1b')); 
$stmt->execute(array(1, '1c')); 
$stmt->execute(array(2, '2a')); 
$stmt->execute(array(2, '2b')); 
$stmt->execute(array(1, '1d')); 
unset($stmt); 

// query data 
foreach($pdo->query('SELECT account,id,someotherstuff FROM Foo') as $row) { 
    echo $row['account'], ' ', $row['id'], ' ', $row['someotherstuff'], "\n"; 
} 

プリント

1 1 1a 
1 2 1b 
1 3 1c 
2 1 2a 
2 2 2b 
1 4 1d 
+0

お返事ありがとうございます。申し訳ありません - 指定されたテーブルはinnoDBです。私は最終的に下の一時テーブルソリューションのために行ったが、入力を感謝します!乾杯! –

+0

ニースの解決策。これは正解です。よく働く。 – SuB

5

は、トリガーを作成します。

CREATE TRIGGER trg_mytable_bi 
BEFORE INSERT ON mytable 
FOR EACH ROW 
BEGIN 
     DECLARE nseq INT; 
     SELECT COALESCE(MAX(seq), 0) + 1 
     INTO nseq 
     FROM mytable 
     WHERE account = NEW.account; 
     SET NEW.seq = nseq; 
END; 
+0

OPにMySQL 5があると仮定... – Ben

+0

あなたの応答に感謝しますが、結局私は上記の一時テーブルソリューションに行きました。 –

+0

混乱しているエラーに問題がある人は、トリガーでデリミタを使用する方法についてはこちらを参照してください:http://stackoverflow.com/questions/5814153/error-in-your-sql-syntax-creating-mysql-trigger – Druckles

関連する問題