いつもお世話になります。
以下のデータ構造において、以下の条件にあてはまるレコードを
取得するにはどのようなSQLになりますでしょうか。
(1)同一のコード、区分において、有効期間開始日が最新のもの
(2)同一のコード、区分、有効期間開始日において、有効期間終了日が最新のもの
【テーブル】
※主キー:コード、区分、有効期間開始日、有効期間終了日
コード 区分 有効期間開始日 有効期間終了日 名前
10000 A01 19800101 99991231 名称1
10000 A01 20000101 99991231 名称2
20000 A01 19800101 19991231 名称3
30000 C01 19800101 19991231 名称4
30000 C01 19800101 99991231 名称5
30000 B01 20000101 99991231 名称6
40000 D01 19800101 99991231 名称7
40000 D01 20000101 20201231 名称8
↓
【取得結果】
10000 A01 20000101 99991231 名称2
20000 A01 19800101 19991231 名称3
30000 C01 19800101 99991231 名称5
30000 B01 20000101 99991231 名称6
40000 D01 20000101 20201231 名称8
ようするに、最新データの名前のデータを取得したいのですが、その最新の
定義が上記にあげたものになります。
連続投稿になってしまい申し訳ないのですが、どうしてもスマートな
SQLを思いつかず、皆様のお知恵をお借りしたいと思った次第です。
宜しくお願いします。
No.5ベストアンサー
- 回答日時:
質問者さんはスルーされていますが、#1さんのSQLも十分スマートだと思いますが・・・。
#1さんは EXISTS 句の中身だけ書かれている様だったので、それ以外を補完してみました。
------------------------------------
SELECT * FROM テーブル T1 WHERE NOT EXISTS
(SELECT 1 FROM テーブル T2
WHERE T1.コード = T2.コード
AND T1.区分 = T2.区分
AND ( T1.有効期間開始日 < T2.有効期間開始日
OR T1.有効期間開始日 = T2.有効期間開始日
AND T1.有効期間終了日 < T2.有効期間終了日));
------------------------------------
参考URL:http://codezine.jp/article/detail/907
おっしゃるとおりです。
自分がSQLを読むことができなかったため気づくことができませんでした。
( T1.有効期間開始日 < T2.有効期間開始日
OR T1.有効期間開始日 = T2.有効期間開始日
AND T1.有効期間終了日 < T2.有効期間終了日)
の部分を解釈することができていませんでした。
exits句の補足もありがとうございました。これがあったから気づくきっかけになりました。
このSQLも十分スマートですね。
ありがとうございました。
No.4
- 回答日時:
実行していません。
マニュアルを見ただけです。http://msdn.microsoft.com/ja-jp/library/ms186734 …
select コード, 区分, 有効期間開始日, 有効期間終了日, 名前
from (
select コード, 区分, 有効期間開始日, 有効期間終了日, 名前, row_number() over(partition by コード, 区分 order by 有効期間開始日 desc, 有効期間終了日 desc) as グループ毎連番
)
where グループ毎連番 = 1;
No.3
- 回答日時:
(1)同一のコード、区分において、有効期間開始日が最新のもの
(2)同一のコード、区分、有効期間開始日において、有効期間終了日が最新のもの
という書き方では、
【テーブル】
コード 区分 有効期間開始日 有効期間終了日 名前
30000 C01 19800101 19991231 名称4
30000 C01 19800102 99991231 名称5
30000 C01 20000101 20111231 名称6
というデータがあれば(別の理由から、ないと思うけど)、
「名称5」がでるのが正しいのか「名称6」がでるのが正しいのか不明なため
(1)同一のコード、区分において、有効期間開始日が最新のもの
(2)(1)が複数取得できる場合において、有効期間終了日が最新のもの
として書くと
select コード,区分,有効期間開始日,有効期間終了日,名前
from tableA T1
where
T1.有効期間開始日 =
(select max(T2.有効期間開始日) from tableA T2
where T1.コード = T2.コード and T1.区分 = T2.区分)
and
T1.有効期間終了日 =
(select max(T3.有効期間終了日) from tableA T3
where T1.コード = T3.コード and T1.区分 = T3.区分 and T1.有効期間開始日 = T3.有効期間開始日)
※一般には、上記の「名称5」がでるのが正しいのか「名称6」がでるのが正しいのか不明な状況にならないように対策をとっているため(以下のようになるようにしているはず)
単に同一のコード、区分において有効期間終了日が最大もデータを取得すればいいはずです。
コード 区分 有効期間開始日 有効期間終了日 名前
30000 C01 19800101 19991231 名称4
30000 C01 19800102 19991231 名称5
30000 C01 20000101 20111231 名称6
30000 C01 20120101 99991231 名称5
select コード,区分,有効期間開始日,有効期間終了日,名前
from tableA T1
where
T1.有効期間終了日 =
(select max(T2.有効期間終了日) from tableA T2
where T1.コード = T2.コード and T1.区分 = T2.区分)
といった感じです。
・・・対策がうまく取れていなければおかしなデータがでてきますが。
回答ありがとうございます。
確かに、普通なら終了日にはかぶらないMAX値が入ると思いますし、開始日と終了日にはかぶらない期間が指定されると思います。
(その期間はその名称だった、というのを意味すると思われる)
期間を持つテーブルの場合、普通は開始日のみ主キーとなっていると思いますが、なぜか開始日と終了日が入っており、登録しようと思えば
質問に出したようなデータも登録できるわけで、万が一登録されていたとしても、それなりに動いてくれる作りにしておきたいのです。
データ登録不備だから2件データがとれて正常に動作しなかった、というのは避けたいのです。
No.2
- 回答日時:
SELECT * FROM テーブル T1
WHERE 有効期間開始日=(SELECT MAX(有効期間開始日)
FROM テーブル T2
WHERE T1.コード = T2.コード
AND T1.区分 = T2.区分)
AND 有効期間終了日=(SELECT MAX(有効期間終了日)
FROM テーブル T2
WHERE T1.コード = T2.コード
AND T1.区分 = T2.区分
AND T1.有効期間開始日=T2.有効期間開始日)
ORDER BY 1,3
です。
先の質問に続き、回答ありがとうございます。
確認してみて意図したとおりに動作しました。
正直前回に引き続き、今回もどのようなSQLにすればスマートなのか思いつかなかったのですが、すごいと思います。
SQL作成において、どのようにアプローチしていますでしょうか。
もしよかったら、教えて頂けるとうれしいのですが。。。
宜しくお願いします。
No.1
- 回答日時:
NULLが絡むとややこしいかもしれませんが、
( SELECT 1 FROM テーブル T2
WHERE T1.コード = T2.コード
AND T1.区分 = T2.区分
AND ( T1.有効期間開始日 < T2.有効期間開始日
OR T1.有効期間開始日 = T2.有効期間開始日
AND T1.有効期間終了日 < T2.有効期間終了日 ) );
回答ありがとうございます。
自分のSQL読解力が弱かったために気づくことができませんでした。
スマートなSQLですね。どのようにしてこのようなSQLを組み立てているのでしょうか。
教えて頂けるとうれしいのですが・・・
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- 電車・路線・地下鉄 大汐線について。いつから休止していますか? ずっと貨物線ですか?(旅客線だった期間はない?) 2 2022/10/11 17:09
- Visual Basic(VBA) VBAで最新のデータを別シートに転記する方法をお教えください。 3 2022/04/07 19:20
- アルバイト・パート 短期バイトについて 3 2023/08/05 20:59
- Visual Basic(VBA) エクセルのマクロコードの一部分を変更する方法について教えてください。 2 2023/02/17 08:40
- Excel(エクセル) エクセルのマクロについて教えてください。 1 2023/02/21 09:28
- 面接・履歴書・職務経歴書 過去に取った資格の名称が現在は変更されてたら 6 2022/09/20 19:35
- 英語 英語の相の種類 Wikipediaでは He began to talk.(起動相) He cont 1 2023/06/26 11:54
- Bluetooth・テザリング android(Galaxy S-22)、bluetoothの「この端末名」がコロコロ変わる 1 2022/12/17 13:15
- その他(Microsoft Office) Microsoft Office Specialist 2019のエキスパート認定について 2 2023/06/24 05:40
- 教育学 高等学校は中等教育機関なのにその名称に”高等”がついており違和感ありまくりです。 他にも旧学制では中 4 2022/04/11 23:27
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Access終了時の最適化が失敗?
-
一度のSQL発行で結果を得るには...
-
Order by句でバインド変数を使...
-
CREATE テーブルでの複数外部...
-
SQLの集計について教えてくださ...
-
DoCmd.ApplyFilter引数を文字に...
-
沿線コード
-
SQLで<>を使用するとき、
-
Oracle 文字コードについて
-
〜のような結果を出すためのSQL...
-
初心者Mysqlの関数のsubstring...
-
ACCESSで大量の更新を行うと「...
-
ファイル書込みで一行もしくは...
-
Accessで別テーブルの値をフォ...
-
Date型にNULLをセットしたい V...
-
Accessでのレコード存在チェック
-
Excelで、改行がある場合の条件...
-
DataGridViewの、選択されてい...
-
使うべきでない文字。
-
実績累計の求め方と意味を教え...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Access終了時の最適化が失敗?
-
CREATE テーブルでの複数外部...
-
Order by句でバインド変数を使...
-
沿線コード
-
ヤマト急便のチェックデジット...
-
SQLServer 日付が直前のレコー...
-
困っています。ORACLE_SQL 複数...
-
Excelファイルのデータをテーブ...
-
SQL 特定のカラムが最大値のレ...
-
10営業日前の日付を取得したい...
-
平成20年 春期 基本情報技術者 ...
-
スペシャリストの方! 助けてく...
-
【SQL】またぎデータの検索の仕方
-
SQLの質問
-
SQLについて
-
SQLの実行結果が異なる
-
SQLにて縦を横へ展開
-
DoCmd.ApplyFilter引数を文字に...
-
Access Dlookup関数について
-
RDBの親子関係の表現について
おすすめ情報