知識不足ですみませんが、
以下の場合の◎の内容が出力できるSQL文を教えてください。
同一のコードが複数あり、有効日時が異なる場合、更新日時に近いレコードを取得したいです。
テーブルの例を記述します。
---------------------------------------
tableA
---------------------------------------
コード | 名称 | 開始日時 | 終了日時
A01 | あ | 2012-04-01 |2014-03-01
A01 | 亜 | 2015-04-01 |2018-03-01
A02 | い | 2012-04-01 |2014-03-01
A02 | 位 | 2015-04-01 |2018-03-01
---------------------------------------
---------------------------------------
tableB
---------------------------------------
コード | 名称 | 開始日時 | 終了日時
B01 | う | 2012-04-01 |2014-03-01
B01 | 宇 | 2015-04-01 |2018-03-01
B02 | え | 2012-04-01 |2014-03-01
B02 | 絵 | 2015-04-01 |2018-03-01
---------------------------------------
---------------------------------------
tableC
---------------------------------------
Aコード | Bコード | 更新日時
A01 | B01 |2012-04-01
A02 | B02 |2013-04-01
A01 | B01 |2014-04-01
A02 | B02 |2015-04-01
---------------------------------------
---------------------------------------
◎SQLで出力したい内容◎
---------------------------------------
Aコード | A名称 | Bコード | B名称 | 更新日時
A01 | あ | B01 | う | 2013-04-01
A02 | い | B02 | え | 2014-04-01
A01 | 亜 | B01 | 宇 | 2015-04-01
A02 | 位 | B02 | 絵 | 2016-04-01
---------------------------------------
※DBはoracleです。プログラムに実装ではないので、sql文が知りたいです。
よろしくお願い致します。
A 回答 (4件)
- 最新から表示
- 回答順に表示
No.4
- 回答日時:
めんどくさい検索条件が必要ならば SQL を使わないほうが良いです。
複雑怪奇な SQL は極端な性能劣化とかデッドロック発生とか保守性とか...
というわけで
テーブルを正規化して条件を簡単にしましょう
または
PL/SQL を書きましょう
No.3
- 回答日時:
No.2 お礼への回答
> 日時比較に不等号ではなくbetweenを使う理由
たいした理由であはありませんが、between の方が性能が良いとされています。
実際の業務においては「A以上B未満」のケースもあるので、
全てに場合で使えるわけではありませんが。
あとは個人的に、こちらの方が読みやすいので。
> 結合にinner joinを使う理由を是非教えていただけますか。
C に対応する A,B が「必ず一つ」存在する前提で書いたので内部結合にしましたが、
必ず、でなければ以下のどちらかを選んでください。
* 内部結合 inner join で、問題の有るレコードを除外して出力
* 外部結合 left outer join で、問題の有るレコードでも穴あきで出力
あと、
> 他案③結合しない場合
それは内部結合を WHERE 句で書くやりかたです。
SQLが大規模化したときに、検索条件と結合条件がごっちゃになって
読みづらくなるのでオススメしません。
Oracle8 の頃は SQL92 標準の JOIN 句が使えなかったり、
Oracle9 で使えるようになっても性能的に問題があったりと、
いろいろあって昔は結合を WHERE 句で書く習慣がありましたが、
現在はオラクル社の奨励でも JOIN 句となっています。
ご回答ありがとうございます。
between の方が性能良いのですね。結合の仕方についても勉強になりました。
>実際の業務においては「A以上B未満」のケースもあるので
すみません。仕様を五月雨にお伝えしてしまい申し訳ないのですが、
C.upd_dt between A.from_dt and A.to_dtに当てはまらないケースもあります。
そのケースに対応すべく、以下の条件を加えたいです。
現在有効なデータ(C.upd_dt between A.from_dt and A.to_dt)がなければ、
① C.upd_dt < A.from_dt(更新日時より未来のデータ)の名称を表示、①がなければ、
② C.upd_dt > A.to_dt(更新日時より過去のデータ)の名称を表示させる。
「なければ」という優先度をつけたSQLの問合せ方法はあるのでしょうか。
No.2
- 回答日時:
同一コードにおいて有効期間をかぶらないように登録する前提、
ならば以下でよいかと。
前提が崩れると途端に変な結果となりますのでご注意ください。
select A.code, A.name, B.code, B.name, C.upd_dt
from C
inner join A on A.code = C.codeA and C.upd_dt between A.from_dt and A.to_dt
inner join B on B.code = C.codeB and C.upd_dt between B.from_dt and B.to_dt
ちなみに、出力したい内容の
A02 | い | B02 | え | 2014-04-01
については、該当する有効期間が見つからないので、
条件に日付計算をする必要があるかもしれません
回答ありがとうございます。遅くなりすみません。
出力したい内容通りに動かすことができました。
しかし、以下の他案①~③でも同じ結果を得られました。(データのバリエーションは試してないですが)
日時比較に不等号ではなくbetweenを使う理由と、結合にinner joinを使う理由を是非教えていただけますか。
他案①日時の比較をbettweenから不等号とした場合
他案②inner join からleft outer joinを使う場合
他案③結合しない場合
SELECT A.code,A.name,B.code,B.name,C.upd_dt FROM C,A,B
WHERE A.code=C.codeA AND B.code=C.codeB
AND (以下省略。日時の比較はbetweenでも不等号でも出力できました。)
No.1
- 回答日時:
select ... from C
inner join A on A.code = C.codeA and ...
inner join B on B.code = C.codeB and ...
になると思いますが、
質問では以下が不明確ですので、これ以上は書けません
* 更新日時に近いレコード、の判断方法
* C.更新日時 → 出力したい内容.更新日時、の変換方法
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
副問合せにLIKE文を使う方法は...
-
IPアドレスを数値に変換
-
batファイルでのSQL(oracle)...
-
oracleのimpdpでORA-39166
-
バッチファイルで複数フォルダ...
-
【SQL】IN句内のサブクエリが重...
-
SQL 2つのテーブルとSUBSTRING...
-
update文で質問です。 下記の条...
-
osqleditについて
-
sqlで質問です。 Aテーブルは店...
-
SQLの中上級者へのレベルアップ...
-
SELECTによる表の変換方法を教...
-
開発対象となるアプリケーショ...
-
質問です。 下記のテーブルとデ...
-
Oracleですがsqlで質問です。 ...
-
sqlで質問です。 Aテーブルの登...
-
sqlで質問です。 Aテーブルの情...
-
SQLの書き方について
-
SQLについて教えて下さい。 主...
-
sqlで質問です。 idを元にidに...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
下記の問合せを行うクエリを、P...
-
SQLです。こんな感じですか?あ...
-
サブクエリを使用せずにLEFT JO...
-
現在庫算出方法についてお教え...
-
SQLで漢字名称を都道府県や市区...
-
うまくいきません教えてくださ...
-
access結合クエリを編集可能に
-
下記の問合せを行うクエリを、P...
-
Access 出荷管理簿を作りたい...
-
このSQLあってますか?教えてく...
-
SQL CASE文に制御について
-
SELECT文内での条件分岐
-
UPDATEでSETする値
-
条件付データ差分の抽出で
-
ACCESS2010 SQL 結合キーにつ...
-
Accessでデータシートに同じデ...
-
L2SWはARPテーブルを持っている?
-
テーブル名をカラムとして取得...
-
SELECT 文の NULL列は?
-
男性と2人で飲食店に行きテーブ...
おすすめ情報
回答ありがとうございます。
* 更新日時に近いレコード、の判断方法
→実は判断方法から悩ましいのですが、同一コードにおいて有効期間をかぶらないように登録する前提のため、
・更新日時より終了日時が大きい(=有効なデータである)
・かつ、終了日時が小さい(=直近)
と判断しようと考えていました。
なので、MIN(終了日時)で 更新日時<終了日時を条件にし
AやBtblから名称を取得できればいいなと考えましたが、
どうにも意図した出力ができません。
* C.更新日時 → 出力したい内容.更新日時、の変換方法
→すみません、イメージが間違ってました。
C.更新日時と出力したい内容.更新日時は同一データの予定です。
(変換の予定はなく、そのまま出力する形です。)
Cの更新日時は、間違っており、Cの更新日時を、出力したい内容の更新日時に読み替えていただけますでしょうか。よろしくお願いいたします。