• ベストアンサー

レコードの選択の仕方

sqlのチューニングが得意なOracle Master所有者です。 ちょっとわからないことがあるので教えてください。 KEY1, KEY2でソートし、 ・先頭レコード ・最終レコード ・項目A1~A100の値が変わったレコード を出力したいのですが、どうすればよいでしょうか? レコード数は約7万で、「SQLで」驚速で処理したいです。 中間テーブルを使用して、特別なインデクスや編集を使用する例でも構いません。 例)★が出力するレコード KEY1 KEY2 A1 A2 A3 ... A100 A 1 0 1 0 0 ★ A 2 0 1 0 0 A 3 0 2 0 0 ★ A 4 0 2 0 0 A 5 0 1 0 0 ★ A 6 0 2 0 0 ★ ... A 60 0 2 5 0 ★ B 1 0 1 0 0 ★ B 2 0 1 0 0 B 3 0 0 0 0 ★ B 4 0 0 1 0 ★ B 5 0 0 1 0 ... B 70 0 2 5 0 ★ C 略

  • Oracle
  • 回答数2
  • ありがとう数0

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

  • ベストアンサー
  • MZ-80B
  • ベストアンサー率56% (46/81)
回答No.1

激速を要求してトリッキーな手法も含むのであれば 厳密なバージョン、エディション、更新頻度、テーブル定義を 載せるのが良いです。 従属項目の属性、値域、カーディナリティはかなり重要ですから そちらも提示した方がなお良しです。 チューニングが得意と前置きして激速と回答者に高い敷居を設けるのであれば まずは、自分の書いたボーダーとなるSQLを明示することが必要でしょう。 あと自分ならば、 このようなマニアックな質問するのに 穴場的存在と思えるこの場を選ばないだろうな~と思います。

ktktkota
質問者

補足

ふむむ。 結局、ナンバーを row_number()で付与し、ナンバーが1番違うのを比較することにしました。

その他の回答 (1)

  • kazu1213
  • ベストアンサー率60% (3/5)
回答No.2

PL/SQLによるテキストファイル出力例(/tmp/test.txt)です。 ※ 項目間は半角スペース declare  ftype utl_file.file_type;  chead varchar2(1000) := 'key1 key2';  data_old varchar2(1000) := ' '; ncount integer;  n integer := 1;  cursor c1 is   select key1,key2,       A1 || ' ' || A2 || ' ' || ‥‥ || ' ' || A100 data   from tbl   order by key1,key2; begin  ftype := utl_file.fopen('/tmp','test.txt','w');  for i in 1..100 loop   chead := chead || ' A' || to_char(i,'FM999');  end loop;  utl_file.putf(ftype,chead || '\n');  select count(*) into ncount from tbl;  for c1_rec in c1 loop   if c1_rec.data != data_old or n = ncount then      /* 先頭レコード or 変更レコード or 最終レコード? */    utl_file.putf(ftype,c1_rec.key1 || ' ' || c1_rec.key2                    || c1_rec.data || '\n');   end if;   data_old := c1_rec.data;   n := n + 1;  end loop;  utl_file.fclose(ftype); end; /

関連するQ&A

  • 前後のレコードを取得する

    SQL初心者です。 以下のようなテーブルがある時に、 -------- X Y Z -------- 1 c E 2 a C 3 d B 4 b A 5 e D -------- 「Xが3のレコードの、Zで昇順ソートした時の前後のレコードを取得する」 ということをしたいのですが、見当もつかずに困っています。 どんな些細なことでもよいので、何かご存知の方がいたら、アドバイス願えないでしょうか。 よろしくお願いします、

  • サブクエリーでデータが存在しないレコードを取得したいです

    サブクエリーで指定したb_masterにレコードが存在せず、a_masterにレコードがある人のデータを取得したいのですが、以下のSQLを変更して実現可能でしょうか? SELECT * FROM user_master as u WHERE code='6' AND (u.code,u.username) = (SELECT code, username FROM b_master as b WHERE b.no = '38' AND b.status >= 1 AND b.code = u.code AND b.username = u.username ) よろしくお願いいたします。

  • 別テーブルの検索した結果が0件のデータのレコードを削除したい

    SQL Server 2005 を使用しています。 別テーブルで検索した結果が0件の時、対応するレコードを削除したいのですが、SQLをどうかけば実現出来るかわかりません。 具体的には、テーブル Aとテーブル B があって、テーブル Aのキーが AA,AB,ACとします。 この時、テーブル Bにも AA,AB,ACという列があるとします。 この時に、テーブルBをAA,AB,ACでGROUP BYしてCOUNTをとった時にレコード数が0のキーのレコードを、テーブルAから削除したいのですが、この時SQLを一つで書きたいのです。 テーブル Aが明細、テーブル Bが名簿みたいな形で、名簿に存在しないレコードを削除するような感じです。 どういうSQLを書けばいいか少し悩んでいます。 AA,AB,ACは全て integer型です。 どなたかわかりましたら教えてください。

  • SQLについて

    A B -------------------------------------------- 1111111             22222222222 -------------------------------------------- nullまたはブランク       33333333333 -------------------------------------------- 12121212           nullまたはブランク -------------------------------------------- 上記のようなレコードがあります。(A,Bはカラム名) 並べ替えを行いたいのですが、条件があります。 カラム名Aをキーにして並べ替えを行いたいのですが、 もしカラム名Aにデータがない場合は、変わりにBのデータを使用して並べ替えを行いたい、というものです。上記の場合、この条件で並べ替えるときは、1レコード目のAの値と、2レコード目のBの値、3レコード目のAの値でソートしたいということになります。このような並べ替えの方法をご存知の方がいらっしゃいましたら、ご教授ください。大変困っています。 DB:ORACLE8

  • 抽出対象の1レコードを複数レコードへ変更し出力する方法を

    抽出対象の1レコードを複数レコードへ変更し出力する方法を SQLで教えてください。(SQLServer2000です。) <イメージ> 店番 顧客番号 年月  A B C D ・・・(Dのあと100項目つづく)・・・ 1000 12345678 200909 10 20 30 40 2000 12345678 200910 30 40 50 60 を 店番 顧客番号 年月  AからD 1000 12345678 200909 10 1000 12345678 200909 20 1000 12345678 200909 30 1000 12345678 200909 40 2000 12345678 200910 30 2000 12345678 200910 40 2000 12345678 200910 50 2000 12345678 200910 60 と出力したいのですが、SQLServer2000ではPIVOT等が使用できず。 抽出処理が思いつきません。 パフォーマンスも悪くなったりしますか。 何か良い方法をご教示ください、よろしくお願い致します。

  • 最大値を含むレコードの抽出

    あるテーブルから、最大値を持つレコードのキーと最大値だけでなく、そのレコードの値を出したいと思います。 最大値をもつレコードを抽出して、元のレコードと結合するしか方法はないのかなと思い、類似した質問があるような気もするのですが、条件が異なるとうまく行かないため、自分なりに考えてみました。 データベースはDB2です。 SELECT a.倉庫,a.品目,a.単価 FROM 在庫マスタ as a where (a.品目,a.単価) in (select b.品目, max(b.単価) from 在庫マスタ as b group by b.品目) つまり、副問合せするときの結合キーが複数あるとSQLがエラーになってしまうようなのです。 結合キーが2つ以上ある時、このようなパターンの対処方法は無いでしょうか?

  • SQLiteで最も古いレコードのみの削除

    AndoroidでDBを使うのですが、考える動作のSQL文が作成できません。 テーブルTESTは以下のカラムを持ちます  ・ID - primary key not null  ・VALUE - not null テーブルTESTは最大で10件のレコードを保持します、11件目のレコードが発生したら 最も古い1件目のレコードを削除してから、11件目のデータを新しい10件目のデータとして テーブルに保存します。 そのために「最も古いレコード1件のみを削除する」というSQLを作成したいのですが、 考えたSQL文が正しくないと怒られてしまいます。 delete from TEST as A, (select * from TEST LIMIT 1)as B where A.ID=B.ID; この動作を1つのSQL文で行うのは不可能なのでしょうか?

  • DELETE 文とEXISTSの使い方について(Oracle10g)

    DELETE 文とEXISTSの使い方について(Oracle10g) 2つのテーブル(A、B)を外部結合して、B側がNULLとなったレコードを A側から削除する、というDELETE文が作りたいのですが、 EXISTS句を使ってみたもののどうも使い方がわからず苦戦しています。 目的は2つのテーブルを同期させる事で このSQLを実行する時点で、常にA>Bになっています。 目的を達成できるSQLを教えてください。 <削除対象レコードをSELECTするSQL> SELECT * FROM A, B WHERE A.KEY1 = B.KEY1(+) AND A.KEY2 = B.KEY2(+) AND B.KEY1 IS NULL ; <上をDELETE文にしてみたつもりが、削除0件になってしまうSQL> DELETE FROM A WHERE EXISTS( SELECT 1 FROM B WHERE A.KEY1 = B.KEY1(+) AND A.KEY2 = B.KEY2(+) AND B.KEY1 IS NULL ) ;

  • ある条件でのSQLの取得方法について

    以下の条件でのSQLのデータの取得方法が分かりません。 2つのテーブルがあるとします。 ・テーブルA キー   項目1 10     X 20     Y ・テーブルB キー  項目2  項目3 10     5    C 10     6    D 12     6    E ここで取得する条件として ■テーブルAにあるのは、必ず取得します。 ■テーブルAのキーとテーブルBのキーは繋がり、繋がったテーブルBの情報は  別レコードとして取得します。 ■テーブルAのキー1つに対して、テーブルBのキーは無いかも知れないし、  複数件あるかも知れません。  無い場合はテーブルAの情報のみを出力し、複数件ある場合はその全てを出力します。 ■テーブルBの項目2が同じ値のデータがある場合、テーブルBを出力したレコードと  同じレコードに、項目2が同じデータの情報を出力します。  項目2が同じデータが無い場合はこの情報は出力しません。  項目2が同じ値のデータは最大2件しかありません。 上記の例の場合に出力したい結果 ・出力テーブルC キー  フラグ   項目1  項目2  項目3   項目2が同じキー  項目2が同じ値 10  テーブルA   X 10  テーブルB         5    C 10  テーブルB         6    D        12            E 20  テーブルA   Y (テーブルC のフラグとは、テーブルAの情報かテーブルBの情報かを示します) これを出来ればSQL、出来なければPL/SQLで取得したいのですが どちらの場合でも取得の方法に悩んでいます。 どのような方法で取得できるのでしょうか?

  • 2つの項目が重複するレコードを抽出する方法はありますか?

    MySQL4.1で既存データに対し複合キーを新しく設定したいのですが、 ALTER TABLE `test` ADD PRIMARY KEY (`a`,`b`) としても重複データが存在する為、作成できませんでした。 10万件あるテーブルから重複するレコードを手動で削除したいのですが、aとbが重複しているレコードだけ抽出するSQL文はありますでしょうか?

    • ベストアンサー
    • MySQL