質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

Q&A

解決済

1回答

1535閲覧

sql 未来価格がある場合は未来価格を表示、現在価格がある場合は現在価格を表示したい。

amakusa

総合スコア176

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

0グッド

1クリップ

投稿2016/12/22 02:33

編集2016/12/22 02:38

現在、賞品一覧に対して1つだけ価格を表示したいのですが、
なかなかクエリが決まらず困っています。
どなたかお力添えをお願い致します。

■現状
賞品マスタ、賞品情報マスタ、賞品価格マスタという3つのテーブルがあり、
1つの賞品に対して、新しく価格ができるたびに賞品情報マスタと賞品価格マスタが1つずつ作成されていきます。
賞品情報マスタは賞品マスタIDを持っており、賞品価格マスタは賞品情報マスタIDを持っています。
賞品価格マスタには、最新価格であればたつ最新価格フラグを持っています。

パターン1:現在日時が20161201の場合に下記のような2つの価格がある場合は、現在適応範囲の価格1を表示します。
価格1:100円 開始日20160401 終了日20170331
価格2:200円 開始日20170401 終了日99991231

賞品一覧表示結果:100円

パターン2:現在日時が20161201だが、価格が未来から始まるものしかない場合はその価格を表示します。
価格1:300円 開始日20170401 終了日99991231

賞品一覧表示結果:300円

1つのViewを用いてこのように制御したいのですが、
どう書いたらいいかわからず困っています。

sql

1select * 2from 賞品マスタ a 3inner join 賞品情報マスタ b on a.id = b.賞品id 4inner join 賞品価格マスタ c on b.id = c.賞品情報id 5where sysdatetime() between 価格開始日 and 価格終了日

こう書くと、未来価格しかないものがこぼれてしまいます。
かといって

sql

1select * 2from 賞品マスタ a 3inner join 賞品情報マスタ b on a.id = b.賞品id 4inner join 賞品価格マスタ c on b.id = c.賞品情報id 5where (sysdatetime() between c.価格開始日 and c.価格終了日) 6or c.価格開始日 > sysdatetime()

と書くと、未来価格と現在価格どちらもある場合に、1つの賞品に対して2つの価格が出てしまうのでNGです。

現在価格がある場合は現在価格を、未来価格のみの場合は未来価格を表示したいです。

どなたか宜しくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

動作確認してないし、これより良い方法がある気がしますので参考程度に。

sql

1select *, 2 RANK() OVER ( 3 PARTITION BY a.id, b.商品情報id 4 ORDER BY 5 CASE WHEN c.価格開始日 > sysdatetime() THEN 1 ELSE 0 END 未来日付フラグ ASC, 6 c.価格開始日 DESC 7 ) AS 日付優先順位 8from 賞品マスタ a 9inner join 賞品情報マスタ b on a.id = b.賞品id 10inner join 賞品価格マスタ c on b.id = c.賞品情報id 11where (sysdatetime() between c.価格開始日 and c.価格終了日) 12or c.価格開始日 > sysdatetime()

ご提示の2つ目のクエリのSELECT部分に、RANKの部分を追加しています。この部分を簡単に説明すると、同一商品(a.id,b.商品情報idの組み合わせが同じもの)内で、現在日付を優先的にした順位付けをするといったものです。

ご提示のパターン1の場合は
価格1:100円 開始日20160401 終了日20170331 日付優先順位1
価格2:200円 開始日20170401 終了日99991231 日付優先順位2
のような行が取得できます。

パターン2のような1行しか無い場合は
価格1:300円 開始日20170401 終了日99991231 日付優先順位1
といった感じです。

あとは上記のSQLをサブクエリとして、そこから日付優先順位が1のレコードを抜き出せばいいです。

sql

1 2select 3 * --アスタリスクだと日付優先順位列も取れてしまうため、本当は列1つ1つ指定する必要があるけど... 4from ( 5 select *, 6 RANK() OVER ( 7 PARTITION BY a.id, b.商品情報id 8 ORDER BY 9 CASE WHEN c.価格開始日 > sysdatetime() THEN 1 ELSE 0 END 未来日付フラグ DESC, 10 c.価格開始日 DESC 11 ) AS 日付優先順位 12 from 賞品マスタ a 13 inner join 賞品情報マスタ b on a.id = b.賞品id 14 inner join 賞品価格マスタ c on b.id = c.賞品情報id 15 where (sysdatetime() between c.価格開始日 and c.価格終了日) 16 or c.価格開始日 > sysdatetime() 17) T 18where T.日付優先順位 = 1

投稿2016/12/22 03:29

編集2016/12/22 03:38
hitsujimeeee

総合スコア486

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

amakusa

2016/12/22 05:22

この回答を応用してやったら見事にできました! 感謝しかありません!ありがとうございます!!!! 優先順位をつける、というのは知らなかったのでとても勉強になりました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問