• ベストアンサー

複数レコードのテーブルであるレコードだけ増やしたい

お世話になります。 複数レコードがあるテーブルにて、あるレコードだけカウントアップする為のSQL文はどのように記述すれば良いでしょうか? 要件: テーブル名'名簿'の No, 名前, 更新者, 備考に 01, 芥川龍之介, ほげ太, NULLを入力し 備考は書き込みさせるためとりあえずNULLを代入しておき 名前と更新者は同じで、Noの部分だけを01~10までカウントアップさせたい 何卒、ご教授のほど、宜しくお願いします。

  • fjsk
  • お礼率82% (19/23)

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

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

こんにちは! すでにSiegrune様よりいい回答が出ておりますので ご質問の回答だけさせていただきますね。 > とても初歩的なご質問で恐縮なのですが、LPADでNoを+1して埋める件ですが > ぱっと思いついたのがMAXで最後の数字を取得することだったのですが > LPADの方がスマートだということでしょうか? SELECT MAXだとSELECT文が2つ入る形になってしまい 見辛いかな?…と思って上記関数を使用しました。 (そうせねば実現不可とか、速度的にということであればやりますが…) 特にスマートとかではありませんが、 この程度のSQLであればそこまで性能を求めなくても 見やすさ優先でいいかな?…という安直な考えです。 深い意図はございませんので(^^; > それから、WHEREで他から取得するのと、分かっている内容なので > 普通にVALUEで書いてしまうのとはどちらの方が良いのでしょうか? 今回の場合であればどちらでもいいと思います。 NOだけでPKになる構造のようですし。 これが更新者ごとにNOをインクリメントしていくとか 名前ごとに…となった場合、いちいちNOを探すのは面倒ですよね? そんな時WHEREから取得するようにしておけば 事前にSELECTをかけなくて済むから楽なワケですよ。 要するに、ある程度汎用性があるように書いてみたというところです。 > 範囲を付けないと永遠に追加されていくのではないかと思われます 1回の実行で1行しか入らないと思ってましたが…。 あ、NOが範囲外になる可能性のことですか? それなら間違いないです(汗) 汎用的になってる分、範囲の設定は必要でしょうね。 (if NO < 30 thenみたいな設定もあれば適当にコピペでも問題なさそうです) プログラム全般そうですが、実現方法は本当に色々ですよね。 色んな引き出しが作れるようにガンバっていきましょう!

fjsk
質問者

お礼

bvltiggeariさま 毎度、ご丁寧に返信くださいましてありがとうございます。 普段はDBまわりの仕事をしていないので、こうやってヒントを戴けると とても勉強になります。本当に様々な手法があり その中に皆さんの工夫が見受けられ、なかなか面白い分野だなと思いました。 これからも教えられる側になれるように精進します!

その他の回答 (4)

  • yamada_g
  • ベストアンサー率68% (258/374)
回答No.5

postgreSQLはほとんど触ったことがないのですが、 generate_seriesという関数があるようですね。 http://www.postgresql.jp/document/8.1/html/functions-srf.html これを使って、 insert into 名簿 select s.n, '芥川龍之介', 'ほげ太', NULL from generate_series(2,10) as s(n) ; という感じでも出来るかもしれません。

fjsk
質問者

お礼

yamada_gさま ご回答くださいましてありがとうございます! これは良いですね、集合を返すのもそうですが 範囲が決められるので一石二鳥かもしれません! しかもいろいろ調べていると基本的なものは同じですが RDBMSによっても便利な関数が用意されていたりして なかなか奥の深い分野だと思いました。 素晴らしい回答、ありがとうございました。

  • Siegrune
  • ベストアンサー率35% (316/895)
回答No.3

insert into 名簿 select No,名前, 更新者, 備考 from (select '芥川龍之介' as 名前, 'ほげ太' as 更新者, NULL as 備考), (select '01' as No union select '02' as No union select '03' as No union select '04' as No union select '05' as No union select '06' as No union select '07' as No union select '08' as No union select '09' as No union select '10' as No ); でできると思うけど。(未検証ですが。)

fjsk
質問者

お礼

Siegruneさま ご回答ありがとうございました! なるほどです、UNIONでマージしていくということですね。 少ない件数の場合はこれで良さそうです。 初歩的なことなのかもしれませんが思いつきもしなかったです、とても参考になります!

回答No.2

さっきカテゴリがあるのに気が付きました。 (にわかでした…) PostgreSQLなんですね。 バージョンが分からないですが INSERT INTO 名簿 (NO, 名前, 更新者) SELECT to_char(NO + 1, '00'), 名前, 更新者 FROM 名簿 WHERE 名前=芥川龍之介 AND 更新者=ほげ太; で、どうでしょう? 上手くガンバって改造して下さい。

fjsk
質問者

お礼

bvltiggeariさま 連続でご返信ありがとうございました! > さっきカテゴリがあるのに気が付きました。 >(にわかでした…) いえいえ、私なんかこのご返信が補足で書き込むのか お礼で書き込むのかさえも分かっていないほどでございます・・・ > バージョンが分からないですが PostgreSQL 8.1.21という、社内で放置されたサーバに載っているRDBMSです。 さて上記ですが、範囲を付けないと永遠に追加されていくのではないかと思われますが こうやってカウントアップさせていく方法がいくつもあるのだということが 勉強出来てとても参考になります。

回答No.1

こんにちは! 「SQL」と書いてあるだけでOracleなのかMySQLなのか PostgreSQLなのか分からなかったので、 自分が1番得意(?)なMySQLで書かせていただきます…と INSERT INTO 名簿 (NO, 名前, 更新者) SELECT LPAD(NO + 1, 2, '0'), 名前, 更新者 FROM 名簿 WHERE 名前=芥川龍之介 AND 更新者=ほげ太; って感じでしょうか。 (0埋め用のLPADが方言だったりするので、お使いのDBに合わせてください) これをカウントアップしたい数の分(10件追加したいなら10行) コピペすればイケるんじゃないかと思います。 (オートコミットじゃない場合にLPAD(NO + 1, 2, '0')の部分どうなるんだろう…) 注意点としては、 1.予め同様のデータ(最初のカウントのデータ)が1行入ってること 2.NOの桁数をLPADの第2引数に入れること 3.プライマリーキーは考慮されてないこと です。 「いいじゃん別に~!」と言われたらそれまでなのですが、 恐らく備考欄が書き込まれた分、追加するのではないかと思います。 そういう場合、名前と更新者で1なのに対し備考がNの関係になるので テーブルをFKで分けて登録させていくのが定石です。 名簿テーブル  NO 名前 更新者 備考テーブル  備考NO 名簿NO 備考内容 みたいな感じの方がメンテナンス面でもいいと思いますし、 慣れておいた方がよいかと…。 余計なことまで言ってすいません…。

fjsk
質問者

補足

bvltiggeariさま ご返答下さいましてありがとうございます! >「SQL」と書いてあるだけでOracleなのかMySQLなのか > PostgreSQLなのか分からなかったので、 大変失礼しました。PostgreSQL板に投稿致しましたので それで明示したつもりでおりまして MySQLのスペシャリストから観て戴けるとはつゆ知らず記入しませんでした。 申し訳ありません。 さらに足りなかったこととしまして、まずなにがしたかったかをご説明しますと 30人の方にアンケートを採り、欲しい・好きな本を10冊挙げよというもので 人数と質問の数が決まっているのと、通常運用するものではないので プログラミングで記入時にレコードを作成するロジックを省いて 先にDBに用意しておこうと思い、SQL文で追加してしまおうと考えたのがきっかけです。 なので、名簿というテーブル名と名前、更新者というのが 混乱させてしまう要因だったのですが、名前というのは作者名で 更新者が記入者という関係性になりまして (最初からそうすれば良かったと反省しておりますが  当初自分だけ分かれば良かったので安易な名前にしてしまいました…) 備考欄に複数の方が書き込むことはなく、予めこちらで決めた記入者が どういうところが好きなのかや欲しいのかを記入するものになります。 (あともう一つ本のタイトル項目がありますが備考と同じと考え省きました) このようにいろいろと至らない点があり反省しているのですがご質問させて下さい。 とても初歩的なご質問で恐縮なのですが、LPADでNoを+1して埋める件ですが ぱっと思いついたのがMAXで最後の数字を取得することだったのですが LPADの方がスマートだということでしょうか? それから、WHEREで他から取得するのと、分かっている内容なので 普通にVALUEで書いてしまうのとはどちらの方が良いのでしょうか?

関連するQ&A

  • ACCESS2007で同じテーブルから繋ぐことはできますか。

    ACCESS2007で同じテーブルから繋ぐことはできますか。 実際に作るのはもっとテーブル数も項目も多いので、不明な箇所だけを簡略した例は次のものです。 都道府県テーブル:K_No、都道府県名 名簿テーブル:M_No、名前、本籍地、居住地(2か所にK_Noは入れられませんよね?) 本籍地と居住地には都道府県.K_Noを入れたいのですが、一つの都道府県テーブルのNoを名簿テーブルの本籍地と移住地の2箇所にリンクすることはできますか。 名簿.M_No、名簿.名前、名簿.本籍地、都道府県.都道府県名、名簿.居住地、都道府県.都道府県名でクエリを作りましたら、 都道府県から名簿へリンクの線が2本出るクエリでは、本籍地と居住地が同じものだけが抽出されました。 都道府県(No)-(本籍地)名簿(居住地)-(No)都道府県_1と3テーブルになると全レコードは表示されますが、本籍地も居住地も居住地のNoの名前が出てしまいます。 本籍地用と居住地用の都道府県テーブルを別に用意しなければならないのでしょうか。何箇所同じ地方コードを入れる箇所(本籍地、居住地、勤務地、別居家族の居住地など)があるので一つのテーブルを共有できたら、と思っています。

  • 複数レコードの複数フィールドを一括UPDATE出来ますか?

    顧客テーブルを更新テーブルのデータで更新したい。 No.顧客テーブル = No.更新テーブル です。 更新フィールドは、年齢、県 です。 ●更新テーブル No 年齢  県 --- ----- ------- 1  30  埼玉 2  30  埼玉 3  30  埼玉 ●顧客テーブル(現) No 年齢  県 --- ----- ------- 1  20  千葉 2  20  千葉 3  20  千葉 4  20  神奈川 5  20  福岡 ●顧客テーブル(更新後) No 年齢  県 --- ----- ------- 1  30  埼玉 2  30  埼玉 3  30  埼玉 4  20  神奈川 5  20  福岡 この場合、1つのSQLで、複数レコードの複数フィールドを一括でUPDATEは出来ますでしょうか?

  • クエリでカウントしつつ、チェックボックスを

    クエリでカウントしつつ、チェックボックスを使えるように(更新できるように)したいです。 アクセス2003です。 テーブル1(主キーなし) 名前   退職(Yes/No型) 佐藤   No 田中   No 佐藤   No から下のクエリを作りました。 SELECT テーブル1.名前, Count(テーブル1.名前) AS 名前のカウント, テーブル1.退職 FROM テーブル1 GROUP BY テーブル1.名前, テーブル1.退職; 結果、 名前 名前のカウント 退職 佐藤   2        No 田中   1        No となりますが、退職フィールドにチェックを入れることは出来なくなってしまいます。 カウントしつつ、更新可能なクエリにしたいのですが不可能でしょうか? 最終的には、このクエリ1をレコードソースとしてフォームに表示させたいです。 ご教示よろしくお願い致します。

  • Is NULLを使わず、NULL項目をWhere条件で取得する方法

    ID・名前・カナ・備考の4項目をもつ氏名テーブルがあり、同じ名前・カナのレコードはまとめてしまいたいと考えています。 IDは最小のものを、備考は全レコードをくっつけて一つのレコードにする予定です。 Group Byしてcount(*)>1の名前・カナを抜き出し、抽出した名前・カナでWhereしてMIN(ID)や備考をSELECTしたいのですが、カナ=NULLの場合があり、Group ByまではできてもWhereでSelectすることができません。 nvl(カナ,'999999')=nvl(抽出したカナ,'999999')だとWhereで取得することもできるのですが、カナ='999999'と入力されているとNULLとの区別がつかなくなります。 Is NULLを使わず、NULL項目をWhere条件で取得する方法をご存知の方、教えてください。よろしくお願いします。 サンプルとして単純なテーブルを例にあげましたが、実際は数十の列項目をもつ数十のテーブルです。列項目の中には4000バイトのものもあります。 完璧にやるのならGroup Byせず、全レコードをOrder Byしてキーが変わったら更新するというやり方が望ましいのでしょうが、レコード数が多く、パフォーマンス的にあまり望ましくありません。 できるだけ作業が簡単な方法だと助かります。

  • accessでのテーブルの複製について

    フォームでコマンドボタン(複製)をクリックして、レコードの複製を作成し、同じテーブルに追加しているのですが、例えば項目の連絡事項がnullの時、複製すると、「実行時エラー94:nullの使い方が不正です」と表示されます。 値が入っているときは問題はないのですが。複製元がnullであっても、そのままnullのまま問題なく複製するには、下記の記述をどうすればいいのでしょうか? Private Sub 複製_Click() Dim bikou As String Dim renraku As String 'カレントレコードの値を取得 bikou = Me!備考.Value renraku=Me!連絡事項.value '新規レコードに移動 DoCmd.GoToRecord , , acNewRec '各コントロールに値を代入 Me!備考.Value = bikou Me!連絡事項.Value =renraku End Sub

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

    お世話になります。 現在、最新レコードを抽出し外部結合する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に変更) お手数お掛け致しますが、ご教示のほどよろしくお願い致します。

  • mysql 複数テーブルの条件付け摘出

    こんにちは。 初歩的なことだと思うのですが、複数テーブルからのレコード摘出で躓いてしまったのでご教授ください。 以下のような2つのテーブルがあったとして、 table_a ---------------- acount_no / name 1 / aaa 2 / bbb table_b ---------------- acount_no / value / update_at 1 / 0000 / 2012-05-12 2 / 3333 / 2012-05-12 1 / 1111 / 2012-05-13 2 / 5555 / 2012-05-13 table_aのacount_noとnameは必ず必要で、table_bのupdate_atに対応するvalueを条件付けで取り出したい場合はどのようにしたら良いのでしょうか。 レコードに存在しない日付を指定したときには、空欄で欲しいのですが・・・、 acount_no / name / value 1 / aaa / null 2 / bbb / null 例えば、 select a.acount_no,name,value from table_a as a LEFT JOIN table_b as b ON a.acount_no = b.acount_no where b.update_at = '2012-05-14' order by a.acount_no asc とすると結果が0行になってしまいます。 外部結合の使い方が間違っているのでしょうか・・・。 お力添えの程、宜しくお願い申し上げます。

    • ベストアンサー
    • MySQL
  • Accessで条件設定用のテーブルを作成する方法

    Accessの条件設定用のテーブルを作成してクエリで結合する方法について質問があります テーブル名「名簿」(データ数99) ID 名前 役職 1 名前1 部長 2 名前2 次長 3 名前3 NULL 4 名前4 NULL 5 名前5 NULL ・・・ 99 名前99 NULL ※NULLは空欄で役職無し 上記名簿に対して 部長と次長は目標値0 特定の人物は目標値2 それ以外は目標値4 と設定したいのです。 下記の「目標値」のような 条件設定用のテーブルを作成し、 クエリで結合することは可能でしょうか? テーブル名「目標値」(データ数5) 名前 役職 目標値 * 部長 0 * 次長 0 名前3 * 2 名前5 * 2 * * 4 ※「*」はどの値でも関係なくヒットして欲しい クエリの結果としてほしいのは下記のような結果です クエリ(データ数99) ID 名前 役職 目標値 1 名前1 部長 0 2 名前2 次長 0 3 名前3 NULL 2 4 名前4 NULL 4 5 名前5 NULL 2 ・・・ 99 名前99 NULL 4 テーブル「名簿」の内容は変更できないものとします。 同じ結果が得られるのであればテーブル「目標値」は変更可能です。

  • テーブルからレコードを(在れば)検索し、更新する

    テーブルから、指定したレコードを検索し、(存在すれば)フォーム表示し、変更・更新できるようにしたい。存在しない場合は、その旨メッセージを表示し、処理を終える。 レコードの指定は、一意の正数値が入っているnoフィールドを用います。 スタンダードな質問で、初歩的かもしれませんが、悪戦苦闘しています。 Accessだけでは無理でしょうか? VBAでやれるでしょうか? 単体のAccessでは何がやれないのかが、よく分かっていないのです。だれか、HELP!

  • SQL文でご質問です

    ご存知の方がおられましたら、教えて下さい。 下記のように、親テーブルと親子を管理するための親子管理テーブルがあります。 条件として、CD1の1が指定された時、親テーブルよりNOが2のレコードと(これは親子関係がないレコード) 親子関係のレコードの親レコードであるNOが1のレコードと子レコードであるNOが11の3レコード を1つのSQL文で取得したいのですが、可能でしょうか? ご存知の方がおられましたら、ご教授のほどよろしくお願い致します。 親テーブル(OYA_TBL) NO,BN1,CD1 ------------- 1,4,NULL 2,NULL,1 3,NULL,NULL 11,4,1 12,4,2 13,4,NULL 親子管理テーブル(OYA_KO_TBL) GOODS_NO,PACK_GOODS_NO ------------- 1,11 1,12 1,13 ↓ [取得結果] NO,BN1,CD1 ------------- 1,4,NULL 2,NULL,1 11,4,1