[pgsql-jp: 31504] Re: PostgreSQL v.s. Access

SAKATA Tetsuo sakata.tetsuo @ lab.ntt.co.jp
2003年 11月 19日 (水) 11:40:44 JST


こんにちは。坂田@昨夜は茅場町(謎)です。

>> Toshio Uchiyama wrote:
>>> 	先日、Access VBAで、変数を使いデータベースのデータ処理をする
>>> 方法があるということを当MLで、伺い。ちょっと、暇をみて勉強し、VBAを
>>> 組んでみました。やったことは、データベースに25,000件のテーブルと
>>> 440,000件のテーブルがあり、25,000件のテーブルをフェッチし、440,000件
>>> のテーブルにどれだけ、25,000件のテーブル中のデータがあるか調べる
>>> ことです。
>> 上記の課題(テーブルT1中のデータで、テーブルT2に出現するものを求める)って、
>> 普通のSQLで join すれば求まるように思います(※)。
> 
> 確かに,440,000件のテーブルと25,000件のテーブルの等価結合をとれば
> 上記に書いたことは達成できるのですが.話はそこでおわらなくて,そこで
> 見つかったデータを440,000件のデータから消し,消したデータのバックアップ
> をとるところまでやって,初めて仕事が終ります.何をやっているか分かっちゃう
> と思いますが.ここまでをSQLでやろうとしたんですが,私の実力ではできなかっ
> たので,プログラムで処理しようと考えています.
> 
> すなわち,現段階は,仕事の途中ですが,PostgreSQL とAccess のどちらで
> データ処理システムを組めば良いか,当たりをつけている段階です.
> 
> もし,上記の仕事を SQL 文で可能なら,教えて頂きたいです.

なるほど。そういう処理がしたいわけですね。

テーブルT1 = t1(*id1, c1)  // 44万件入り。
テーブルT2 = t2(*id2, c2)  // 2.5万件入り。

と仮定します。*id1, *id2 はそれぞれのテーブルにて同一性を識別するための
キー(参照キー)なっているとします。

	--	--	--	--

まず、バックアップを取ります。バックアップすべきデータは、

SELECT * FROM t1 WHERE t1.id1 = t1.id2; // (Ex.1)

で求まりますね。普通のファイルに書き出すのであれば、
カーソルを使って1行ずつ書き出すのが標準SQL的な方法ですね。
(PostgreSQLだと、表をまるごと書き出すようなうまい命令があるかも)

ファイルを使わずに、全部DB内に閉じた方法でやるなら、
つまり、バックアップ先もDBのテーブルにするなら(それをt3とします);

INSERT INTO t3
  SELECT * FROM t1 WHERE t1.id1 = t1.id2;

とすればよいですね。

次に、それを削除するのは、

DELETE FROM t1
  WHERE t1.id1 = t2.id2;

とやれば、t1, t2に出現するデータをt1から削除できますね。

気になるのは、1回joinして求めた表の内容を、再度求めているという点です。
(無駄ですよね)

これを回避するには、最初のEx.1で求めた問い合わせ結果をカーソルで読み出しつつ、
t1から該当する行を取り出してバックアップし、完了後に削除する、という方法があります。

あと、複数のSQL文で操作する場合には、トランザクション的な観点でのチェックも
必要ですね。SERIALIZABLE で実行すれば問題ないと思います。

以上、ご参考になれば幸いです。
-- 
坂田 哲夫@NTT サイバースペース研究所
sakata.tetsuo _at_ lab.ntt.co.jp
SAKATA, Tetsuo. Yokosuka JAPAN.




pgsql-jp メーリングリストの案内