644 :
NAME IS NULL :
05/03/01 23:38:59 ID:6E4qrgjn 下記のようなことを行いたいのですが、もう数十時間悩んでおり、このままだとクビになります。 以下のようなテーブルが2つあります ■テーブルA 顧客ID なまえ 内線 ―――――――― 001、 佐藤、 001 ※同じ(これだけ残す) 002、 鈴木、 002 003、 田中、 003 004、 佐藤、 001 ※同じ(削除) 005、 佐藤、 004 006、 鈴木、 005 007、 佐藤、 001 ※同じ(削除) ■テーブルB 伝票ID 顧客ID 購入物 001、 001、 ガム ※対応する顧客は残る 002、 003、 チョコレート 003、 004、 塩 ※対応する顧客が残らない 004、 006、 ガム 005、 002、 塩 006、 007、 塩 ※対応する顧客が残らない テーブルAの佐藤4人中3人は、名前も内線も同じなので 顧客IDは一番小さいものだけ残し、あとは同一とみなし重複行を削除します。 そうするとテーブルBの伝票IDの001、003、006の顧客IDは全部が佐藤だったのですが 重複を削除してしまったため、003と006に対応する顧客がテーブルAから消えてしまいます。 なので、テーブルAの重複を削除するときに、同時にテーブルBの顧客IDも 一緒に一番小さい顧客IDに更新したいのです。 どうか宜しくお願いいたします。
>>644 ワークテーブルとか作れますか?
顧客IDが一番小さいものだけ、ワークテーブルに突っ込むと、方法に広がりがでると思う。
646 :
644 :05/03/02 00:33:55 ID:SXcU4gI8
ワークテーブル? その話もう少し詳しく聞かせてください
DBにもよるけど。 1.別なテーブルに、残す分のレコードを待避しちゃう(テーブルC)。 Oracleなら、create table as select *・・・がつかえる。 2.テーブルBの顧客IDに該当するテーブルAのレコードの内線番号に該当するテーブルCの顧客IDで、 テーブルBの顧客IDを更新。 3.テーブルAを全部削除して、テーブルCの内容を insert 4.テーブルCを drop で、どうだ?
一時表をおすすめします。データがほかのセッションと混じらないし、たしかログ対象で ないので余分なログを書き出さないというメリットがあったと思います。 Oracle (おそらく9以降)なら事前にアロケーションしておきます。 CREATE GLOBAL TEMPORARY TABLE table_name ... INSERTしたデータはそのセッションからしか見えず、セッションが終わればそのデータが消えます。 MSSQL だと表名に@をつけるだったかな。こっちは実行時にアロケーションします。 CREATE TABLE @table_name ... 表自体がセッション内でのみ有効でセッションが終われば表ごと消えます。
649 :
644 :05/03/02 07:12:31 ID:SXcU4gI8
>647、648 色々とご助言ありがとうございます。 しかし私はOracleビギナー中のビギナーなもんで まったく理解できません。 できれば例文でSQLをご教授いただければと思います。 わがまま言ってすいません
650 :
NAME IS NULL :05/03/02 08:47:19 ID:6sCbSKMl
ライムワイヤー関係のスレ教えてください
>>649 Oracleならサブクエリーがいろいろ使えるから、こんな感じのViewかワークテーブルを作るといいですよ。
select t1.顧客ID, t2.統一顧客ID from テーブルA t1 join
(select なまえ, 内線, min(顧客ID) as 統一顧客ID from テーブルA group by なまえ, 内線) t2
on (t1.なまえ = t2.なまえ and t1.内線 = t2.内線);
もしjoinが使えないバージョンだったら普通にwhereで結合してくださいね。
>>648 訂正、MSSQLの一時テーブルは #テーブル名でした。Oracle9i 10g ではこんな感じにかけます。
create global temporary table TableC (CsID number(3) primary key,
CsName nvarchar2(4), CsITel number(3), TrueCsID number(3));
ここまでは事前の作業、フィールド名が変わってるけど推測してください。
insert into TableC (CsID, CsName, CsITel, TrueCsID)
select t1.CsID, t1.CsName, t1.CsITel, t2.TrueCsID from TableA t1 join
(select CsName, CsITel, min(CsID) as TrueCsID from TableA group by CsName, CsITel) t2
on (t1.CsName = t2.CsName and t1.CsITel = t2.CsITel);
update TableB t1 set CsID = (select TrueCsID from TableC t2 where t1.CsID = t2.CsID);
delete from TableA where CsID in (select CsID from TableC where CsID <> TrueCsID);
commit; -- ここでTableCのデータは消去される。
誰かビューについて教えて下さいー。 複雑なSQLがあったとして、そのSQLを元にビューを作成したとします。 この場合、ビューを参照した時というのは、裏で作成元となったSQLが参照する度に実行されていて、 実行結果を得る時間は、ビューの作成元となったSQLを実行する場合と同じなのでしょうか? それとも、一度ビューを作成すれば、Oracleが裏で何かしてくれていて、毎回ビューの作成元となった SQLを実行するよりも、実行結果を早く得る事が出来るのでしょうか? 私は、ビューというのは見せたくないカラム等を隠すための、セキュリティ的な意義しかないと思っていたのですが、 先日会社の先輩が、ビューを作れば、ビューの作成元となったSQLを実行するより早く実行結果を得られると言っていたので・・・. 一応、Oracleのオンラインドキュメントには目を通したのですが、ビューについてはセキュリティ的な意義しか 書いてありませんでした。 どなたか知ってたら教えて下さい。お願いします。