C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[6]: 範囲指定をしてデータを取得したい


(過去ログ 112 を表示中)

[トピック内 14 記事 (1 - 14 表示)]  << 0 >>

■66358 / inTopicNo.1)  範囲指定をしてデータを取得したい
  
□投稿者/ にしよこ (1回)-(2013/04/17(Wed) 21:32:58)

分類:[データベース全般] 

Oracle10g使用です。

No│ID  │有効開始日│有効終了日
─┼───┼─────┼─────
1 │1111 │20120401 │20130131
2 │1111 │20130201 │99991231

上記のようなテーブル(A)があるとして、以下の条件でデータを取得したいのですが思うように取得できません。

条件1:有効開始日が「00000000」から、有効終了日が「20130331」まで
    → SELECT * FROM A WHERE ID = '1111' AND 有効開始日 >= '00000000' AND 有効終了日 <= '20130331'
      このSQLだと、有効期間が終了したデータ(No.1)が取得されてしまいます。

条件2:有効開始日が「20130101」から、有効終了日が「99999999」まで
    → SELECT * FROM A WHERE ID = '1111' AND 有効開始日 >= '20130101' AND 有効終了日 <= '99999999'
      このSQLは思うように取得できます。

条件3:有効開始日が「20130101」から、有効終了日が「20130331」まで
    → SELECT * FROM A WHERE ID = '1111' AND 有効開始日 >= '20130101' AND 有効終了日 <= '20130331'
      このSQLだと、データが取得できません。

※仕様は、「キー(ID)が重複するデータが取得できる場合は最終データを取得する」です。


このようなデータ取得を実現できるSQLをご教授願えませんでしょうか?
初心者なので、上記のようなSQLしか思いつきません。

宜しくお願いします。

引用返信 編集キー/
■66359 / inTopicNo.2)  Re[1]: 範囲指定をしてデータを取得したい
□投稿者/ shu (283回)-(2013/04/17(Wed) 23:47:42)
No66358 (にしよこ さん) に返信
> ※仕様は、「キー(ID)が重複するデータが取得できる場合は最終データを取得する」です。

SELECT ID, 有効開始日, 有効終了日
FROM (
    SELECT ID, 有効開始日, 有効終了日 ,
       ROW_NUMBER() OVER(PARTITION BY ID ORDER BY 有効終了日 DESC) row_num
    FROM A
) B
WHERE row_num = 1

SQL Serverはこれで出来ますがOracleで同じ構文かわかりません。PARTITION BYは
使えると思うので調べてみてください。

引用返信 編集キー/
■66360 / inTopicNo.3)  Re[2]: 範囲指定をしてデータを取得したい
□投稿者/ にしよこ (2回)-(2013/04/18(Thu) 00:09:16)
No66359 (shu さん) に返信
> ■No66358 (にしよこ さん) に返信
>>※仕様は、「キー(ID)が重複するデータが取得できる場合は最終データを取得する」です。
>
> SELECT ID, 有効開始日, 有効終了日
> FROM (
> SELECT ID, 有効開始日, 有効終了日 ,
> ROW_NUMBER() OVER(PARTITION BY ID ORDER BY 有効終了日 DESC) row_num
> FROM A
> ) B
> WHERE row_num = 1
>
> SQL Serverはこれで出来ますがOracleで同じ構文かわかりません。PARTITION BYは
> 使えると思うので調べてみてください。

返信ありがとうございます。

最終データを取得する部分は既知です。
すみません、書き漏れていました。

参考までに重複データの場合の仕様を書き込みましたが
メインの質問は、範囲指定をしたデータ取得方法です。

引き続き、よろしくお願いします。
引用返信 編集キー/
■66363 / inTopicNo.4)  Re[1]: 範囲指定をしてデータを取得したい
□投稿者/ 裕猫 (52回)-(2013/04/18(Thu) 08:56:57)
No66358 (にしよこ さん) に返信
> Oracle10g使用です。
>
> No│ID  │有効開始日│有効終了日
> ─┼───┼─────┼─────
> 1 │1111 │20120401 │20130131
> 2 │1111 │20130201 │99991231
>
> 上記のようなテーブル(A)があるとして、以下の条件でデータを取得したいのですが思うように取得できません。
>
> 条件1:有効開始日が「00000000」から、有効終了日が「20130331」まで
>     → SELECT * FROM A WHERE ID = '1111' AND 有効開始日 >= '00000000' AND 有効終了日 <= '20130331'
>       このSQLだと、有効期間が終了したデータ(No.1)が取得されてしまいます。
このSQL文ならNo.1が有効開始日が「00000000」から、有効終了日が「20130331」までに入っていてno.2は条件からはずれているのでNO.1を返すのは当然の処理です。
あなたの考えている処理通り有効開始日が「00000000」から、有効終了日が「20130331」までのデータを返してきているのに何が問題でしょうか?
> 条件2:有効開始日が「20130101」から、有効終了日が「99999999」まで
>     → SELECT * FROM A WHERE ID = '1111' AND 有効開始日 >= '20130101' AND 有効終了日 <= '99999999'
>       このSQLは思うように取得できます。
>
> 条件3:有効開始日が「20130101」から、有効終了日が「20130331」まで
>     → SELECT * FROM A WHERE ID = '1111' AND 有効開始日 >= '20130101' AND 有効終了日 <= '20130331'
>       このSQLだと、データが取得できません。
これも有効開始日が「20130101」から、有効終了日が「20130331」までのデータはないのでデータの取得ができないのは当然です。やりたいことがわからないので回答のしようがありません。
こういう結果をほしいと書いてくれればアドバイスできると思います。
引用返信 編集キー/
■66364 / inTopicNo.5)  Re[2]: 範囲指定をしてデータを取得したい
□投稿者/ にしよこ (3回)-(2013/04/18(Thu) 09:08:16)
No66363 (裕猫 さん) に返信
> ■No66358 (にしよこ さん) に返信
>>Oracle10g使用です。
>>
>>No│ID  │有効開始日│有効終了日
>>─┼───┼─────┼─────
>>1 │1111 │20120401 │20130131
>>2 │1111 │20130201 │99991231
>>
>>上記のようなテーブル(A)があるとして、以下の条件でデータを取得したいのですが思うように取得できません。
>>
>>条件1:有効開始日が「00000000」から、有効終了日が「20130331」まで
>>    → SELECT * FROM A WHERE ID = '1111' AND 有効開始日 >= '00000000' AND 有効終了日 <= '20130331'
>>      このSQLだと、有効期間が終了したデータ(No.1)が取得されてしまいます。
> このSQL文ならNo.1が有効開始日が「00000000」から、有効終了日が「20130331」までに入っていてno.2は条件からはずれているのでNO.1を返すのは当然の処理です。
> あなたの考えている処理通り有効開始日が「00000000」から、有効終了日が「20130331」までのデータを返してきているのに何が問題でしょうか?
>>条件2:有効開始日が「20130101」から、有効終了日が「99999999」まで
>>    → SELECT * FROM A WHERE ID = '1111' AND 有効開始日 >= '20130101' AND 有効終了日 <= '99999999'
>>      このSQLは思うように取得できます。
>>
>>条件3:有効開始日が「20130101」から、有効終了日が「20130331」まで
>>    → SELECT * FROM A WHERE ID = '1111' AND 有効開始日 >= '20130101' AND 有効終了日 <= '20130331'
>>      このSQLだと、データが取得できません。
> これも有効開始日が「20130101」から、有効終了日が「20130331」までのデータはないのでデータの取得ができないのは当然です。やりたいことがわからないので回答のしようがありません。
> こういう結果をほしいと書いてくれればアドバイスできると思います。

ご返信ありがとうございます。
情報が足らず、すみません。

条件1の場合、No.2も「20130201」から「20130331」で有効期間に含まれると思うので、No.1とNo.2の両方が返ってきてほしいのです。
条件3の場合、No.1は「20130101」から「20130131」で有効期間に含まれ、No.2は「20130201」から「20130331」まで有効期間に含まれるので、両方返ってきてほしいです。

アドバイス頂けたら幸いです。
よろしくお願いします。
引用返信 編集キー/
■66365 / inTopicNo.6)  Re[3]: 範囲指定をしてデータを取得したい
□投稿者/ shu (284回)-(2013/04/18(Thu) 09:24:39)
No66364 (にしよこ さん) に返信

入力は何で
可変条件は何で
固定条件は何で
期待される出力は何でしょう?


引用返信 編集キー/
■66367 / inTopicNo.7)  Re[4]: 範囲指定をしてデータを取得したい
□投稿者/ にしよこ (4回)-(2013/04/18(Thu) 09:33:19)
No66365 (shu さん) に返信
> ■No66364 (にしよこ さん) に返信
>
> 入力は何で
> 可変条件は何で
> 固定条件は何で
> 期待される出力は何でしょう?
>
>

ご返信ありがとうございます。
情報不足ですみません。

入力は期間のFromとToです。
固定条件はIDです。

期待される出力ですが、条件1〜条件3のすべてにおいてNo.1No.2の両方です。
指定された期間がデータをまたがる場合は、その両方のデータを取得したいのです。
(キーが重複する場合には最終データを取得する仕様は、一旦省いています。)

よろしくお願いします。
引用返信 編集キー/
■66369 / inTopicNo.8)  Re[5]: 範囲指定をしてデータを取得したい
□投稿者/ shu (286回)-(2013/04/18(Thu) 09:40:17)
No66367 (にしよこ さん) に返信
>
> 入力は期間のFromとToです。
> 固定条件はIDです。
>

入力:From, To, FindID
でいいですね。

(ID = FindID) And (有効期間開始 <= To) And (有効期間終了 >= From)

でいいですか?
引用返信 編集キー/
■66370 / inTopicNo.9)  Re[6]: 範囲指定をしてデータを取得したい
□投稿者/ にしよこ (5回)-(2013/04/18(Thu) 09:51:27)
No66369 (shu さん) に返信
> ■No66367 (にしよこ さん) に返信
>>
>>入力は期間のFromとToです。
>>固定条件はIDです。
>>
>
> 入力:From, To, FindID
> でいいですね。
>
> (ID = FindID) And (有効期間開始 <= To) And (有効期間終了 >= From)
>
> でいいですか?

ご返信ありがとうございます。

> 入力:From, To, FindID
> でいいですね。

はい。

> (ID = FindID) And (有効期間開始 <= To) And (有効期間終了 >= From)
>
> でいいですか?

このSQLだと1レコード、もしくは該当データなしになりませんか?
引用返信 編集キー/
■66371 / inTopicNo.10)  Re[7]: 範囲指定をしてデータを取得したい
□投稿者/ shu (287回)-(2013/04/18(Thu) 10:05:11)
2013/04/18(Thu) 10:11:38 編集(投稿者)

No66370 (にしよこ さん) に返信
>
> このSQLだと1レコード、もしくは該当データなしになりませんか?

こちらは条件の確認をしているだけですよ。
日本語で書くと
『指定したIDで有効期間が指定期間内のレコード』
となります。


2つの範囲
A1〜B1(A1<B1), A2〜B2(A2<B2)
があったとき

2つの範囲が重なるための条件は
A1 <= B2 And B1 >= A2
となります。

後者が前者の範囲に含まれるための条件は
A1<=A2 And B1>=B2
となります。

2つの範囲が重ならないための条件は
A1 > B2 Or B1 < A2
となります。
引用返信 編集キー/
■66373 / inTopicNo.11)  Re[3]: 範囲指定をしてデータを取得したい
□投稿者/ 裕猫 (53回)-(2013/04/18(Thu) 11:44:32)
No66364 (にしよこ さん) に返信
> 条件1の場合、No.2も「20130201」から「20130331」で有効期間に含まれると思うので、No.1とNo.2の両方が返ってきてほしいのです。
> 条件3の場合、No.1は「20130101」から「20130131」で有効期間に含まれ、No.2は「20130201」から「20130331」まで有効期間に含まれるので、両方返ってきてほしいです。
>
> アドバイス頂けたら幸いです。
> よろしくお願いします。
まだいまいち条件がのみこめませんが要は有効終了日は考慮にいれる必要がないのではないかと思われます。ならば
条件1:有効開始日が「00000000」から、有効終了日が「20130331」まで
    → SELECT * FROM A WHERE ID = '1111' AND 有効開始日 >= '00000000' AND 有効開始日 <= '20130331'
条件3:有効開始日が「20130101」から、有効終了日が「20130331」まで
    → SELECT * FROM A WHERE ID = '1111' AND 有効開始日 >= '20130101' AND 有効開始日 <= '20130331'
とすればno1もの2も拾いますがこれでは有効終了日を見ないのでだめですかね。
引用返信 編集キー/
■66375 / inTopicNo.12)  Re[4]: 範囲指定をしてデータを取得したい
□投稿者/ ピノ (1回)-(2013/04/18(Thu) 16:12:24)
これは、テーブルの有効期間開始〜有効期間終了の期間が、入力したFrom〜Toの期間に少しでも重なっていればOK、という抽出条件でしょうか?
それならば、条件式はもっと複雑になります。
IDの条件は省略すると、以下のような感じになると思いますがどうでしょう。

((有効期間開始 <= From AND 有効期間終了 >= From) OR
(有効期間開始 <= To AND 有効期間終了 >= To) OR
(From <= 有効期間開始 AND To >= 有効期間開始) OR
(From <= 有効期間終了 AND To >= 有効期間終了))
引用返信 編集キー/
■66376 / inTopicNo.13)  Re[5]: 範囲指定をしてデータを取得したい
□投稿者/ shu (288回)-(2013/04/18(Thu) 16:26:12)
2013/04/18(Thu) 16:26:38 編集(投稿者)
No66375 (ピノ さん) に返信
> これは、テーブルの有効期間開始〜有効期間終了の期間が、入力したFrom〜Toの期間に少しでも重なっていればOK、という抽出条件でしょうか?
この条件なら私が提示したのであっているので、複雑にする回答はやめたほうがいいです。

(1)有効期間開始がTo以下    有効期間開始の範囲   ________________To    
(2)有効期間終了がFrom以上  有効期間終了の範囲       From_____________________

のようになるので(1)と(2)を満たせば
有効期間開始〜有効期間終了 と From〜To
は少しでも重なるという条件になります。
※ただしこの条件が成立するのは
 From <= To, 有効期間開始 <= 有効期間終了
 でなければならない。

引用返信 編集キー/
■66377 / inTopicNo.14)  Re[6]: 範囲指定をしてデータを取得したい
□投稿者/ ピノ (2回)-(2013/04/18(Thu) 16:41:38)
2013/04/18(Thu) 16:55:08 編集(投稿者)
なるほど、確かに

> From <= To, 有効期間開始 <= 有効期間終了

の条件下では、以下を考えてみるとその通りですね。

・ケース1
     有効期間開始________________有効期間終了
  From_____________________To

・ケース2
 有効期間開始________________有効期間終了
          From_____________________To

・ケース3
 有効期間開始__________________________________有効期間終了
          From______________To

・ケース4
     有効期間開始_______有効期間終了
  From______________________________________To

DB登録時には少なくとも有効期間開始 <= 有効期間終了であると思いますし、
検索時には入力チェックでFrom <= Toでなければエラーとすればいいわけですからね。

引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -