こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

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

お世話になります。
複数レコードがあるテーブルにて、あるレコードだけカウントアップする為のSQL文はどのように記述すれば良いでしょうか?

要件:
テーブル名'名簿'の
No, 名前, 更新者, 備考に
01, 芥川龍之介, ほげ太, NULLを入力し
備考は書き込みさせるためとりあえずNULLを代入しておき
名前と更新者は同じで、Noの部分だけを01~10までカウントアップさせたい

何卒、ご教授のほど、宜しくお願いします。

投稿日時 - 2012-11-29 04:39:35

QNo.7820942

困ってます

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

こんにちは!

すでに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みたいな設定もあれば適当にコピペでも問題なさそうです)

プログラム全般そうですが、実現方法は本当に色々ですよね。
色んな引き出しが作れるようにガンバっていきましょう!

投稿日時 - 2012-11-30 10:15:47

お礼

bvltiggeariさま

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

投稿日時 - 2012-12-01 05:34:28

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(5)

ANo.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)
;

という感じでも出来るかもしれません。

投稿日時 - 2012-11-30 12:19:25

お礼

yamada_gさま
ご回答くださいましてありがとうございます!

これは良いですね、集合を返すのもそうですが
範囲が決められるので一石二鳥かもしれません!

しかもいろいろ調べていると基本的なものは同じですが
RDBMSによっても便利な関数が用意されていたりして
なかなか奥の深い分野だと思いました。
素晴らしい回答、ありがとうございました。

投稿日時 - 2012-12-01 05:38:37

ANo.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
);
でできると思うけど。(未検証ですが。)

投稿日時 - 2012-11-30 01:16:00

お礼

Siegruneさま
ご回答ありがとうございました!

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

投稿日時 - 2012-11-30 02:14:08

ANo.2

さっきカテゴリがあるのに気が付きました。
(にわかでした…)
PostgreSQLなんですね。
バージョンが分からないですが

INSERT INTO 名簿 (NO, 名前, 更新者) SELECT to_char(NO + 1, '00'), 名前, 更新者 FROM 名簿 WHERE 名前=芥川龍之介 AND 更新者=ほげ太;

で、どうでしょう?
上手くガンバって改造して下さい。

投稿日時 - 2012-11-29 20:36:44

お礼

bvltiggeariさま
連続でご返信ありがとうございました!

> さっきカテゴリがあるのに気が付きました。
>(にわかでした…)

いえいえ、私なんかこのご返信が補足で書き込むのか
お礼で書き込むのかさえも分かっていないほどでございます・・・

> バージョンが分からないですが
PostgreSQL 8.1.21という、社内で放置されたサーバに載っているRDBMSです。

さて上記ですが、範囲を付けないと永遠に追加されていくのではないかと思われますが
こうやってカウントアップさせていく方法がいくつもあるのだということが
勉強出来てとても参考になります。

投稿日時 - 2012-11-30 02:03:38

ANo.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 備考内容

みたいな感じの方がメンテナンス面でもいいと思いますし、
慣れておいた方がよいかと…。

余計なことまで言ってすいません…。

投稿日時 - 2012-11-29 11:48:33

補足

bvltiggeariさま
ご返答下さいましてありがとうございます!

>「SQL」と書いてあるだけでOracleなのかMySQLなのか
> PostgreSQLなのか分からなかったので、

大変失礼しました。PostgreSQL板に投稿致しましたので
それで明示したつもりでおりまして
MySQLのスペシャリストから観て戴けるとはつゆ知らず記入しませんでした。
申し訳ありません。

さらに足りなかったこととしまして、まずなにがしたかったかをご説明しますと
30人の方にアンケートを採り、欲しい・好きな本を10冊挙げよというもので
人数と質問の数が決まっているのと、通常運用するものではないので
プログラミングで記入時にレコードを作成するロジックを省いて
先にDBに用意しておこうと思い、SQL文で追加してしまおうと考えたのがきっかけです。

なので、名簿というテーブル名と名前、更新者というのが
混乱させてしまう要因だったのですが、名前というのは作者名で
更新者が記入者という関係性になりまして
(最初からそうすれば良かったと反省しておりますが
 当初自分だけ分かれば良かったので安易な名前にしてしまいました…)
備考欄に複数の方が書き込むことはなく、予めこちらで決めた記入者が
どういうところが好きなのかや欲しいのかを記入するものになります。
(あともう一つ本のタイトル項目がありますが備考と同じと考え省きました)

このようにいろいろと至らない点があり反省しているのですがご質問させて下さい。

とても初歩的なご質問で恐縮なのですが、LPADでNoを+1して埋める件ですが
ぱっと思いついたのがMAXで最後の数字を取得することだったのですが
LPADの方がスマートだということでしょうか?

それから、WHEREで他から取得するのと、分かっている内容なので
普通にVALUEで書いてしまうのとはどちらの方が良いのでしょうか?

投稿日時 - 2012-11-30 01:47:21

あなたにオススメの質問