• ベストアンサー

欠番の取得方法

いつも参考にさせて頂いています。 MySQL(OS:Windows)でDBを作っていますが、ある問題で詰まってしまいましたので識者の方の意見を伺えればと考えました。 問題は、インデックス(1で開始され、あとは+1ずつ増加)をキーとしたデータが登録されているテーブルがあります。 このテーブルのデータは削除・追加が行われます。削除の際は当然そのインデックスが欠番となり、追加時は欠番があればそちらを使用したいのですが、欠番を求める巧いSQLが思い浮かびません(パッと考え付くのは欠番テーブルを作る事位です…)。 如何せんDB・SQL経験が浅いためDB設計の考え方がおかしいのかもしれません。この点も含め上記問題の解決方法のヒントを教えて頂ければ幸いです。

  • MySQL
  • 回答数2
  • ありがとう数3

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

今、テーブルを t 、インデックスを i とします。 このとき、 次のSQLで、最小の欠番を取得できます。 SELECT MIN(T0.i) + 1 FROM t AS T0 LEFT JOIN t AS T1 ON T0.i + 1 = T1.i WHERE T1.i IS NULL; これは、4.0でも動きます。

hello_world
質問者

お礼

masayuki0511さん遅くなってしまいましたが、回答ありがとうございます。 しかも丁寧なSQL、対応バージョンまで…ひたすら感謝です。 LEFT JOINは不慣れだったためパっと出てきませんでしたが、知人に聞いてどう動くのかが判りました。ちょっと変えると欠番の最大値も求められる便利なSQLですね。ありがとうございました。

その他の回答 (1)

  • vivlet
  • ベストアンサー率36% (24/66)
回答No.1

私がぱっと考えて一番単純なのは、削除時はDELETEでなく削除フラグを立てて、新規時に削除フラグの立っている小さい順にUPDATE か DELETE&INSERT かな? select min(インデックス) from table where 削除フラグ レコードが取得できれば 取得したインデックスを使用。 レコードが取得できなければ MAX+1 で登録。 同じような処理をやってるとこも多そうなので、実際にやったことある人の意見を聞いた方が良いかもですね。

hello_world
質問者

お礼

vivletさん、回答ありがとうございます。 なるほど削除時にDELETEしない方法は気づきませんでした。発想の転換が必要だったことを思い知ります。MySQLで差集合をとる方法を必死で考えていた5分前の自分に教えてやりたい位です(^^;

関連するQ&A

  • IDに欠番があった場合のupdate処理

    お世話になります。 配列でデータを受け取って、下の様な構文を書けばPDOを使用してupdateできますが、 データの削除を行って、idが欠番になった場合の対策として、どの様に書けば良いのかが 分かりません。 ------------------------------------------------- $id = $_POST['id']; $test = $_POST['test']; $sql = "UPDATE test_table SET test = ? WHERE id = ?"; $stmt = $conn->prepare($sql); foreach ($test as $id => $value) { $stmt->execute(array($value, ++$id)); } ------------------------------------------------- もし削除処理が行われたら、欠番の穴埋めを行い、尚且つidは オートインクリメントしているので、最終のidを取得してALTER TABLEで 新規データを追加した際にも欠番が出ないようにしようかとも考えましたが、 効率的とは思えなかったので、もしidに欠番があっても該当する「 id 」に 正常にデータをupdateできる構文をご教示いただきく存じます。 ---------------- ▼スペック PHP 5.3.3 MySQL 5.0.95 ----------------

    • ベストアンサー
    • PHP
  • SQLで取得したフィールドをSQL文として利用

    お世話になっております。 MYSQLで sql_id (int PK) sql_data (text) のようなテーブル(sql_db)を持ち select sql_id from where (sql_data をsqlとして実行した結果 ) > 200 のように、フィールドから取得した値をSQLとして実行したりする方法はございますでしょうか。 ご教授よろしくお願いいたします。

  • MYSQLで異なるテーブル間のデータを参照できますか?

    MYSQLの超素人なので質問自体がおかしいかもしれませんが、あるテーブルのデータを他のテーブルにも利用したいのですが、これは可能でしょうか? もともとの発端は、mysqlのtable_1からデータを引っ張ってくるphpのプログラムがあるのですが、そのtable_1には私の欲しいデータがありませんでした。それでphpmyadmin(私はこれでしかDBをいじれません)を見てみると、table_2に欲しいデータがありました。 この時点で私は ・phpのプログラムをいじってtable_2からもデータを引っ張ってくるようにしたほうがいいのか それとも ・table_1にもう一行(これはなんていうのでしょう・・・ 呼び方が分かりません)追加してtable_2の欲しいデータを引っ張ってきた方がいいのか などと考えてみたのですが、いかんせん、phpもmysqlも全然分からないので、どうしたもんかと思っておりました。それでまだ簡単そうな2番目について質問してみました。が、何か根本的に考え方がおかしい部分などあると思うので、それもあわせて指摘していただけると幸いです。よろしくお願いします。

    • ベストアンサー
    • MySQL
  • MySQLでデータをマージする方法について

    お世話になります。 スキーマが二つあります。db1とdb2です。 それぞれ、同じ構造のテーブルを持っていて、格納しているデータだけが違います。 db1にdb2をマージしようとしているのですが、上手くいきません。 手順としては、以下のとおりです。 (1)まず、db1のダンプを取りました。   (インポート先でテーブルをドロップしないようにオプションを付加)    c:\>mysqldump -u root --add-drop-table=false -p db1>db1.sql (2)次に、db2に接続してダンプしたファイルをインポートしました。    mysql>\. db1.sql インポートの前後で、テーブルの件数を見たのですが、 変わらないのでマージできていないようです。 以下は当方の使用環境です。 Windows7 Pro 64Bit MySQLServer 5.1(mysql-5[1].1.28-rc-win32) 他に必要な情報があればお聞かせください。 よろしくお願いします。

    • ベストアンサー
    • MySQL
  • Query Cacheとインデックスについて

    Query Cacheはテーブルが更新(何かしらのデータが追加)されると有効ではないのでしょうか? 掲示板のデータがinsertされるテーブルを含むデータベースの場合、Query Cacheは無意味なのでしょうか? MySQLのインデックスを再設定したいのですがどのような手順で行うと良いでしょうか? 全てのインデックスを削除して、再度インデックスを張ればいいのでしょうか?

    • ベストアンサー
    • MySQL
  • 配列に配列を足すことはできるか?

    PHPを使ってMYSQLのデータを吐き出すプログラムを作っています。 $re=mysql_query(SQL命令1); でDBに命令し $kekka=mysql_fetch_array($re) で、配列に代入 $re=mysql_query(SQL命令2); でDBの別テーブル(データ型やカラム数は同じ)に命令し $kekkaに情報を足すということがしたいのですが、どのように書けば$kekkaにデータが蓄積されていくのでしょうか?

    • ベストアンサー
    • PHP
  • PHPからMySQL・異なるDBにコピー

    PHPからMySQL・異なるDBに接続し同じ構造のテーブルのデータをコピーすることは可能ですか? 以下を実行するとクエリが実行されず「コピーできません」が表示されてしまいます。 どのようにすればコピーできるか教えてください。 $connect1 = mysql_connect("localhost", "user1", "pass1") ; mysql_select_db("db1", $connect1); //db1内にtable1 $connect2 = mysql_connect("localhost", "user2", "pass2") ; mysql_select_db("db2", $connect2); //db2.内にtable2 $sql = "INSERT INTO `db1` . `table1` SELECT * FROM `db2` .`table2`;"; $result = mysql_query($sql, $connect1)or die("コピーできません"); //$result内「$connect1」でも「$connect2」結果は同じです。 //table1とtable2の構造は同じです。

    • ベストアンサー
    • PHP
  • マスタデータ更新

    こんにちは。 システム開発の基礎的なところがわからないので、教えていただきたく、投稿させていただきます。 システム開発をほとんどやったことがないので、言葉が変なところもあるかと思いますが、宜しくお願いいたします。 サーバー上に、AというSQLServerのDBがあります。 今までは、システム管理者のみがAccessからA.DBのリンクテーブルを使い、マスタデータの更新/追加/削除を行っていましたが、今後、リーダークラスの人もできるようにしたい!という要望があり、そのインターフェース部分を作成しています。 いろいろと考え、フロントエンド側にAccessでB.mdbを作成し、そこには、A.DBと同じテーブル構造の一時TBLを作成し、B.mdbを開いた時にA.DBから全データを取得することにしました。(取得するところまではできています) ここから、設定するための画面作成をしますが、最終的に、更新/追加/削除されたデータは、どのようにA.DBにUPすればいいのでしょうか? 考えた方法として (1)B.mdb内に、一時テーブルとは別に、更に同じ構造の変更用テーブルを作成。 設定画面から更新/追加/削除されたデータは変更用テーブルに保存し、全ての処理が終了したら、変更用テーブルにあるデータを1つづつ見て、A.DBへ更新/追加/削除をかける (2)一時テーブルのデータを直接更新/追加/削除し、全ての処理が終了したら、全テーブルのレコードを1件づつ比較し、A.DBへ更新/追加/削除をかける というくらいしか思いつかないのです。 その他に思ったのが、一時テーブルもしくは変更用のテーブルに、レコード毎に「更新/追加/削除」がわかるようにフラグを設けて、そのフラグに従ったSQL文を発行する というくらいです。。。 根本的に、マスタデータに対する更新/追加/削除のやり方が間違っていたりしますか? 誰も聞ける人がいないので、どうぞ宜しくお願いいたします!!!

  • データの取得方法

    失礼いたします。 SQL文でDBからデータを取得して、それを 表示したいのですがうまくいきません。 どこを間違っているか、どうしたらいいか コメントお願いします。 //他のページからIDを取得 <?php $aid=htmlspecialchars($_GET["id"]); ?> //SQL <?php $sql = "SELECT A.USERID,A.NAME,B.BIL_ID,B.B.BIL_NAME FROM USER A,BIL B WHERE A.BIL_ID=B.BIL_ID AND USER_ID=".intval($_GET["aid"]); !$an = mysql_query($sql,$db) $user = mysql_fetch_row($an); mysql_free_result($an); ?> //データの表示 //SQLで実行した'BIL_ID'を表示したい。 <TD><INPUT type="text" name="bid" value="<?php print(intval($_GET["$user[2]"])) ?>"></TD>

    • ベストアンサー
    • PHP
  • オートナンバー型を1から始める方法はありますか?

    アクセスのVBAで mySQL = "DELETE Tテーブル.* FROM Tテーブル;" DoCmd.RunSQL mySQL を実行して テーブルのデータをすべて削除してから、 データを追加するコードを実行しているのですが オートナンバー型のフィールドが前回の続きの値から始まります。 運用上問題ないのですが 途中の数字から始まってスッキリしません。 削除クエリを実行しても オートナンバー型を1から始める方法はありますか?