データテーブルの変更回数を設定する方法

このQ&Aのポイント
  • データテーブルの変更回数を設定する方法について教えてください。
  • データテーブルには番号と履歴番号のフィールドがあります。番号が2に採番されたとき、履歴番号には1が入ります。
  • 履歴番号が他のレコードの番号と一致する場合、変更回数を設定したいのですが、どのようにすれば良いでしょうか?
回答を見る
  • ベストアンサー

別レコードと比較条件文

別レコードと比較条件文 下記のテーブルがあります。 ・番号1から始まり番号が2に採番されると、履歴番号に番号1が入ります。 ・履歴番号はひとつ前の番号を持ちます。 ・Aテーブルのレコード数は100以上あります。 Aテーブル ID 番号 履歴番号 A 1 NULL A 2 1 A 3 2 B 1 NULL B 2 1 B 3 2 結果として出力させたいのは、変更回数です。 ・履歴番号は実際のデータですと10桁の複雑な文字列です。 ほしい出力結果 ID 番号 履歴番号 変更回数 A 1 NULL 0 A 2 1 1 A 3 2 2 B 1 NULL 0 B 2 1 1 B 3 2 2 行いたい条件式とは、 一行目:履歴番号がNULLのときは変更回数0とする。 二行目:履歴番号が他レコードの番号と一致する場合、1を持つ。そのレコードの履歴回数がNULLなら判定終わり。 三行目:履歴番号が他レコードの番号と一致する場合、1を持つ。そのレコードの履歴番号が更に他レコードと一致する場合、2を持つ。そのレコードの履歴回数がNULLなら判定終わり。 このようにして変更回数を設定したいのですが、思いつきませんのでご教示お願いできますでしょうか。 試してみたのは、DECODE(履歴番号,'','0',番号,1) とまでためしに作りましたが、同じレコード同士の比較になってしまうため、比較できません。

  • force1
  • お礼率55% (713/1288)
  • Oracle
  • 回答数9
  • ありがとう数11

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

  • ベストアンサー
  • papapa0427
  • ベストアンサー率25% (371/1472)
回答No.9

>一行目:履歴番号がNULLのときは変更回数0とする。 >二行目:履歴番号が他レコードの番号と一致する場合、1を持つ。そのレコードの履歴回数がNULLなら判定終わり。 >三行目:履歴番号が他レコードの番号と一致する場合、1を持つ。そのレコードの履歴番号が更に他レコードと一致する場合、2を持つ。そのレコードの履歴回数がNULLなら判定終わり。 と言うこと前提に結論です。SQLでは書けません。フロントエンドでの処理が必要です。 つまり、一行しかヒットしなかった場合は当然履歴番号はNULLですね。でそのIDのレコード取得は終了ですね。 二行ヒットした場合は、NULLデータの処理と履歴を持つレコードの処理が必要になりますね。つまりここで二重作業(レコードの再検索)が必要になります。 さらに三行ヒットした場合、上記に加えて三行目の処理も必要になります。(再度のレコードの再検索) しかしレコード数は一定ではないと推察しますので、一回のSQL文でこの様な全データを取得するのは不可能と考えます。 また常に3レコードあるとすれば何とかなりそうですが3レコード以上の場合もあるとすれば1回のSQL文でこのようなデータを取得するは不可能です。 行うとすれば、ID毎に必要な処理をさせてワークテーブルにINSERTし、更新回数を設定する。出力結果としてワークテーブルの内容を出力するという方法しか今の私には思いつきません。

その他の回答 (8)

  • yorozu_ya
  • ベストアンサー率54% (76/140)
回答No.8

> 同じようなSQL文は試したのですが・・エラーでした。 提示されていないものについてのコメントは出来ません。 > ・start withではなくwithなのでしょうか? 漏れましたね。 ORACLEの無い環境で回答してます。 > ・WHERE句で条件指定したい場合は、withおよびCONNECT BYはどこに入れるのでしょうか? 提示したサイトにすべて解説されています。 ページをめくって見てください。

  • yorozu_ya
  • ベストアンサー率54% (76/140)
回答No.7

考えて欲しかったけど面倒なので回答します。 SELECT ID, 番号, 履歴番号, LEVEL - 1 AS 変更回数 FROM Aテーブル WITH 履歴番号 IS NULL CONNECT BY PRIOR ID = ID AND PRIOR 番号 = 履歴番号;

force1
質問者

お礼

ありがとうございます。 同じようなSQL文は試したのですが・・エラーでした。 ・start withではなくwithなのでしょうか? ・WHERE句で条件指定したい場合は、withおよびCONNECT BYはどこに入れるのでしょうか?

  • yorozu_ya
  • ベストアンサー率54% (76/140)
回答No.6

> NULLのとき始まりが「1」となっております。 > ・これ(今回でいうと変更回数)を「0」始まりにするには、どのように行えばよいでしょうか。 マイナス 1 すればよろしいかと。

force1
質問者

お礼

ありがとうございます。 階層問い合わせはWHERE句の後に記述するのでしょうか? 以下で実行するとエラーがでてしまい変更回数をセットすることができません。 色々なサイトを調べましたが、うまくできません。 select level from A where * start with A.履歴番号 is null connect by prior A.番号 = A.履歴番号

noname#140925
noname#140925
回答No.5

>業務用途です。select以外で行ってもいいのですが思い浮かびませんのでご教示ください。 そのテーブルに変更回数の項目設けておいて、新しい履歴レコードinsertする際に、現在の変更回数に1を加えた値を設定すれば良いだけですが。 何か難しく考えすぎなのでは?

force1
質問者

お礼

ありがとうございます。 なるほど理解しましたが、今回はテーブルに項目を追加せず出力の際に付与してやる形で行いたいと思います。 下記URLの階層手順でできそうですが、 http://codezine.jp/article/detail/2694 NULLのとき始まりが「1」となっております。 ・これ(今回でいうと変更回数)を「0」始まりにするには、どのように行えばよいでしょうか。 ・又今回コード毎にこのような階層条件を行いたいのですが、どのように行えばよいでしょうか。

  • yorozu_ya
  • ベストアンサー率54% (76/140)
回答No.4

> どのような方法でしょうか。 キーワードが提示されたのですから、検索してみてください。 その上で分からない点を質問してください。

force1
質問者

お礼

ありがとうございます。 検索させて頂きましたが、今回の事例でどう使っていけばよいかわかりません。 ヒントをいただけますか。

  • yorozu_ya
  • ベストアンサー率54% (76/140)
回答No.3

階層問い合わせを使えばよろしいかと。

force1
質問者

お礼

ありがとうございます。 どのような方法でしょうか。

noname#140925
noname#140925
回答No.2

ANo1さんも書いていますが、端から変更回数の項目を用意しておいて、insert時に回数を入れておくべきでは? Oracleは趣味で自宅で使用しているのでしょうか? 業務用途だと速度的な事を考えても、select時に計算で行うのは無駄以外の何物でもないと思いますが。

force1
質問者

お礼

ありがとうございます。 業務用途です。select以外で行ってもいいのですが思い浮かびませんのでご教示ください。

回答No.1

こんにちは。 >履歴番号は実際のデータですと10桁の複雑な文字列です。 という事は、番号も同様ですよね? 具体的にどのような文字列なのでしょう・・・? というか、レコード入れるときに振ればいいだけなのに・・・。

force1
質問者

お礼

ありがとうございます。 今回はSQL文で抽出を行いたいのです。 なのでINSERTは使いません。 データを抽出するときに変更回数はオリジナルとして持たせます。 番号も履歴番号も10桁の「A3Jfj389DO」などといった文字列の組み合わせです。

関連するQ&A

  • 条件をつけてレコードを取得したい

    以下のようなA,Bテーブルから条件を指定してレコードを取得したい 【Aテーブル】 ID Bテーブル番号 0001      null 0002      null 0003      null 【Bテーブル】 シーケンス番号   ID    登録日 処理済みフラグ       0010  0001 2014/01/01        0       0011  0001 2014/01/02        1       0012  0001 2014/01/03        0 <結果> 【Aテーブル】 ID Bテーブル番号 0001     0001 0002     null 0003     null 条件としては以下の条件です。 (1)Aテーブルは全レコード出力する (2)BテーブルのAテーブルシーケンス番号が複数存在する場合、登録日が一番古いレコードを抽出する (3)Bテーブルの処理済みフラグが0のレコード以外はnullとする。 自分で抽出条件を作成したのですが、Aテーブルの0001分しか上手く抽出出来ませんでした。 SELECT * FROM Aテーブル AT (SELECT シーケンス番号, MIN(登録日) AS 登録日 FROM Bテーブル GROUP BY AテーブルID) BT1, (SELECT * FROM Bテーブル) BT2 WHERE AT.ID = BT1.ID AND BT1.登録日 = BT2.登録日 AND BT1.ID = BT2.ID AND BT2.処理済みフラグ = '0' 一度上の命令文でテーブルを作って元のテーブルとマッチングさせるしかないのでしょうか?出来れば一発で抜き出したいです。 ご教授宜しくお願いします。

  • 最新レコードを抽出し外部結合する方法について

    お世話になります。 現在、最新レコードを抽出し外部結合するSQLを考えているのですが、実現できておりません。 実現できるSQLをご存知の方、いらっしゃいましたら情報を頂けますでしょうか。 # 私の使用しているのは、PostgreSQL8.3となります。 実現したい内容は、以下となります。  1.テーブルAから「名前」でグループ化して最新の「更新日付」のレコードを抽出。  2.1の結果とテーブルBを「名前」で結合。  3.テーブルAの「名前」、「点数」、「更新日付」とテーブルBの「判定」を抽出。    ⇒ただしテーブルAに情報がある場合は、テーブルBの判定結果を「0」にして出力。      テーブルA               テーブルB ----------------------------   -----------------------  名前| 点数| 更新日付       名前 | 判定  ----------------------------   ----------------------- AAA   98   2011/4/1        AAA   0  AAA   60   2011/4/3        BBB   1  BBB   70   2011/4/2        CCC   1  BBB   35   2011/4/4        DDD   1  DDD   98   2011/4/1        EEE   0  EEE   47   2011/4/5         FFF   0  GGG   80   2011/4/6        GGG   1    【出力結果】 ---------------------------------------------  名前 | 点数  | 更新日付 | 判定  --------------------------------------------- AAA    60     2011/4/3      0  BBB    35     2011/4/4     0(1⇒0に変更)  CCC   NULL     NULL       1  DDD    98     2011/4/1     0(1⇒0に変更)  EEE    47     2011/4/5      0  FFF    NULL     NULL       0  GGG    80     2011/4/6     0(1⇒0に変更) お手数お掛け致しますが、ご教示のほどよろしくお願い致します。

  • 2つのテーブルを比較して、不一致レコードを抽出するSQL文

    2つのテーブルを比較して、不一致レコードを抽出するSQL文を教えてください。まったくの初心者なので、よろしくお願いします。

  • 別のテーブルのレコードを転記したい

    テーブルA:職員番号,氏名,住所 テーブルB:職員番号,給与,住所 このときに2つのテーブルの職員番号が一致するものについてテーブルAの住所をテーブルBの住所に転記(更新)したいのですが、更新クエリとかでできるものですか?

  • if文の判定条件('||'と'&&'の使い方)

    ○if文の判定条件への理解が弱いため、下記プログラムを作成し、 疑問があったため、質問をしたいと思っております。 #include<stdio.h> #include<string.h> int main() { char moji[]= "A"; /***********************************************************/ if( 0 != strcmp( moji , "A" ) || strcmp( moji , "B" ) ) ^^(1) /***********************************************************/ { printf( "文字不一致" ); } else { printf( "文字一致" ); } return (0); } ○質問 「/*/」で囲ったif文の判定箇所になりますが、 この判定条件は"配列mojiに格納されている値が"A",または"B"以外の" ときに、画面上に「文字不一致」を出力します。そうでなければ 「文字一致」を出力します。 今回、配列mojiには"A"が格納されており、「文字一致」が画面に 出力されるはずですが、「文字不一致」が出力されてしまいます。 判定条件が誤っていると思い、色々と試したところ、(1)の箇所を 「&&」にしたときに、「文字不一致」が出力されます。 「||」(論理和)と「&&」(論理積)が理解できていないと思われ、 この部分を交えて、何故「&&」にしないと「画面不一致」と出力 されないのかを、ご教授の程お願い致します。

  • 【SQL】SELECT 文で外部のレコードと比較する。

    こんにちわ タイトルがわかりにくく申し訳ありません。^^;) 【やりたい事】 ○テーブルA に下記のレコードが有ります。 ID FIRSTNAME  LASTNAME 00 ICHIRO     SUZUKI 01 TARO      YAMADA 02 TSUYOSHI   SHINJYO ○テーブルB に下記レコードが有ります。 ID LASTNAME 00 SUZUKI 01 SASAKI ここで テーブルB に登録されている LASTNAME と同じ LASTNAME を持つレコードを テーブルA から抽出する SQL を教えて頂けないでしょうか? この状態で抽出されるレコードは 00 ICHIRO SUZUKI です。 お時間のある時で構いませんので、よろしくお願い致します。

  • 特殊なレコードの取得方法

    下記のようなテーブルがあり、 マスタの方は「*」が入っていれば、デフォルト行のような扱いをしたいのです。 ・テーブルの1のデータはマスタのAと完全マッチしているので、Aの行の値が欲しい。 ・テーブルの2のデータはマスタと完全一致はしないが、列4が「*」なのでBの行の値が欲しい。 ・テーブルの3のデータはマスタと完全一致はしないが、列3と列4が「*」なので、Cの行の値が欲しい。 現在は、マスタを別名で完全一致用(m1)、列4が「*」用(m2)、列3と列4が「*」用(m3)の3つをFrom句に記述し、 Select句にて、m1がNULLなら、m2から取得、m2もNULLならm3から取得するというやり方をとっていますが、 実際の「*」がある組み合わせがたくさんあり、それだけインラインビューを用意すると遅くなっているので、 なんとかインラインビュー1つでなんとかならないものでしょうか? テーブル ┌─┬──┬──┬─┐ │01│AAAA│X001│YY│←1 ├─┼──┼──┼─┤ │01│AAAA│X001│ZZ│←2 ├─┼──┼──┼─┤ │01│AAAA│X002│YY│←3 └─┴──┴──┴─┘ マスタ ┌─┬──┬──┬─┐ │01│AAAA│X001│YY│←A ├─┼──┼──┼─┤ │01│AAAA│X001│* │←B ├─┼──┼──┼─┤ │01│AAAA│* │* │←C └─┴──┴──┴─┘

  • SQL文の書き方(こんなこと出来ますか)

    テーブルA(ID、A,B,中身) テーブルa(A、コードの名前1) テーブルb(B、コードの名前2) ID、A、コードの名前1、B、コードの名前2、中身という風に結果を得たいのですが、Aがテーブルaに存在する、又はBがテーブルbに存在するものを出力したいのですがJoinが良く分かりません。aまたはbに存在しない時はコードの名前はNullにしたく、また抽出されテーブルAのレコードが重複しないようにしたいのですが、考えても分かりません。ご教授下さるようお願い致します。

    • ベストアンサー
    • MySQL
  • レコードの一致方法

    テーブルA(マスター) [コード]、[商品名]        ○○○、△△△ テーブルB [コード]、[商品名]       ○○○、△△△ テーブルC [コード]、[商品名]       ×××、△△△ 以上のように、3つのテーブルの不一致クエリーなどを 抽出する場合、テーブルAとB同士の場合は、一致しないのはコードを結合線で結べば、すぐに出てきますが、テーブルAとCの比較の場合は、コードを結合線で結んだところで、違うのでうまくできません。 商品名は△△△なので、コードが違っていても、商品名はあっているので、不一致ではなく、一致しているというように考えたいのです。 △△△についてのコードは×××、○○○というように2つ以上持っているような感じですれば、うまくいくとおもっているのですが、こういう場合はテーブルAにコードのフィールドを2つ作っておいて、結合線でつなぐときに切り替えてするしかないのでしょうか? テーブルA(マスター)で、このような、2つのコードを持っているとおもわれる商品はレコード100以上あって、それをそれぞれ選びながら入力していかないかとおもうと、大変な作業化とおもっているのですが、アドバイスあればお願いします。

  • NULLを認識させる方法

    Access2000を使用しています。 SQL文について質問です。 AとBの、内容が似たテーブル (フィールド項目は全く同じで入力内容が若干違います) それぞれの'数量'というフィールドを比べ、 内容が一致する件数を出力したいというのが目的です。 方法としてはCOUNTを使用し、 (A.数量)(B.数量)を結合&比較して一致しないレコードが NULL意外のものを件数に数えるようにしたいのです。 しかしIS NULLやIS NOT NULLを使うとTRUEかFALSEが 渡ってしまいます。 そこで質問なのですが、 COUNTを使って、 データが一致しないところがNULLであることを認識させ、 カウントからはずすには、どのようにSQLを作成したら よいでしょうか?