QA@IT

2つのテーブルから1つのテーブルへインサート

2276 PV

以下のようなことをSQLで実現できるか、あるいはPL/SQLなど他の手段なら実現
できるのか、教えてください。

テーブルAが以下の定義であるとします。
ID  販売開始日  販売終了日
(現在0件)

ほかにテーブルB、Cが以下のようになっているとします。
テーブルA
ID  FDATE
 1  2013/09/01
1 2013/09/10
1 2013/09/30

テーブルB
ID  TDATE
1 2013/09/10
1 2013/09/30
1 2013/10/30

このテーブルA,Bからデータを抽出して、テーブルAにインサートして
以下のようにSQLでできるでしょうか?必ずA,Bは同数のレコードがある前提で、
2つの列をくっつけてそのままテーブルAに登録するイメージです。

ID  販売開始日  販売終了日
1 2013/09/01 2013/09/10
1 2013/09/10 2013/09/30
1 2013/09/30 2013/10/30

回答

パッチは後で送りますが投稿前に内容確認してくださいね。

テーブルAに テーブルB,Cから。
また、IDに重複はないものとして、

テーブルA
ID  販売開始日  販売終了日

テーブルB
ID  FDATE
1   2013/09/01
2   2013/09/10
3   2013/09/30

テーブルC
ID  TDATE
1   2013/09/10
2   2013/09/30
3   2013/10/30

普通にjoinすれば行けると思います

insert into テーブルA
(ID, 販売開始日, 販売終了日)
select テーブルB.ID, テーブルB.FDATE, テーブルC.TDATE
from テーブルB 
  inner join テーブルC
  on テーブルB.ID = テーブルC.ID

結合を内部結合にするか外部結合にするかは特に情報がなかったので、内部結合にしています。

修正前の質問の様に、IDが本当にすべて 1 だった場合はくっつけるための規則性がなければ無理です。
また、件数が同じであってもIDが異なる場合があるので、内部結合で良いかどうかは別途ご判断ください。

編集 履歴 (1)
  • 私もflied_onionさんと同じSQLを考えましたが、そもそもテーブルAっているんですかね。冗長なデータをわざわざ記録しなくても、必要なビュー作ればすみそうです。 -
  • @Oakbow さん そうですね。本当にこのテーブルのままであればViewとか、その都度JOINするというのが普通でしょうね。この形でexportしたいからテーブルを作りたいとかでもなければ優位性はない気がします。 -
  • コメントを書きながらデータを眺めてたら、1行目の終了日は2行目の開始日、2行目の終了日は3行目の開始日なんですねぇ。なにか関係あるのか、重要じゃないから適当に日付つけたらそうなっただけなのか・・・。 -
  • flied_onionさん、 Oakbowさんコメントと回答ありがとうございます。これはあるデータを作る過程の処理で、from,toで履歴管理している2テーブルの日付全部をまとめてならべ替えて1テーブルfrom,toにしようとしたものです。回答してもらい助かりました。 -

IDに重複があって
古い順に連結していくということであれば

Select A.ID, A.FDate, B.TDate 
From
     (Select ID, FDate, Row_Number() over(partition by ID Order By FDate) Rn
         From テーブルA) A
  inner join 
     (Select ID, TDate, Row_Number() over(partition by ID Order By TDate) Rn
         From テーブルB) B
  on A.ID = B.ID and A.Rn = B.Rn
Order By A.ID, A.Rn

というのはどうでしょう?PL/SQLと記述されているところをみると環境はOracleのようですが
こちらにはOracle環境がないので若干構文が違うかもしれません。

編集 履歴 (0)
  • Shuさんコメントありがとうございます。仰る通Oracleです。Row_numberを使えば結合できますね。参考になりました。ありがとうございました。
    -
  • Oracleの場合はrownumという強力な行の識別子があるので、ID列が識別子として機能しない場合はこちらを使うことが多いかもしれません。分析関数でも対応できますけれど。 -
  • IDに対し日付順に並び替え番号を振っているので
    rownumは使えないです。

    例えばレンタルビデオ店などで
    同じ商品を貸した日と返された日を別に持っていた場合のような感じではないでしょうか?
    -
ウォッチ

この質問への回答やコメントをメールでお知らせします。