web-dev-qa-db-ja.com

発効日がある価格を保存するには?

製品のリストがあります。それらのそれぞれは、Nプロバイダーによって提供されます。

各プロバイダーは、特定の日付の価格を見積もります。その価格は、そのプロバイダーが新しい価格を設定することを決定するまで有効です。その場合、プロバイダーは新しい日付で新しい価格を提供します。

MySQLテーブルヘッダーは現在次のようになっています。

_provider_id, product_id, price, date_price_effective
_

隔日で、当日有効な製品/価格のリストを作成します。各製品のリストには、その特定の製品を提供するプロバイダーのソートされたリストが含まれています。そのようにして、たまたま最良の価格を提供する人に特定の製品を注文することができます。

実効価格を取得するために、date_price_effective >= NOW()を含むすべての行を返すSQLステートメントがあります。その結果セットは、次のようなファイルを取得するために必要なソートとフィルタリングを行うRubyスクリプトで処理されます。

_product_id_1,provider_1,provider_3,provider8,provider_10...
product_id_2,provider_3,provider_2,provider1,provider_10...
_

これは私たちの目的には問題なく機能しますが、SQLテーブルはおそらくこの種の情報を格納するための最良の方法ではないという悩みがあります。この種の問題は以前に他のより創造的な方法で解決されたと私は感じています。

SQL以外でこの情報を格納するより良い方法はありますか?または、SQLを使用している場合、私が使用しているアプローチよりも優れたアプローチはありますか?

21
edmz

時間に応じて変化するアイテム(たとえば、「日付DのXの価格は何でしたか」または「日付EのフィードロットQにいた牛」などに答えることができるなど)については、「時間指向の開発SQLのデータベースアプリケーション。」この本は絶版になっていますが、著者は本のPDFおよび関連するCDを彼のWebサイトで提供しています。

http://www.cs.arizona.edu/~rts/publications.html (「books」の下の最初の項目を探します)。

オンラインでの簡単な紹介については、以下を参照してください。

17
Tangurena

私は確かにデータベースに発効日を保存します。結局のところ、人々がクエリを実行して価格が時間の経過とともにどのように変化したかを確認したり、過去の製品価格表に対して注文の奇妙さをクロスチェックしたりしたいと思うでしょう。実行しているクエリのタイプと価格変更の頻度に応じて、現在の価格と過去の価格の別々のテーブルを用意することは理にかなっています。

価格を保存するほとんどのシステムでは、有効日付に加えて有効期限列を使用すると、現在有効な価格を簡単に判別できます。これにより、前または次の行を調べて図を表示する手間が省けます。特定の時点で有効だった価格私はあなたのNOW() >= date_price_effective条件が何をしているのかはっきりしていません-おそらく、それは私には奇妙に思われる以前のすべての過去の価格とともに現在の価格を返します。 「実効価格」はNOW() BETWEEN date_price_effective AND date_price_expiredのようなもので定義される現在の価格になると思います

また、ファイルがどのように表示されるかはわかりません。 provider_1が何を表すか-provider_id = 1価格?-またはプロバイダーデータの注文方法-provider_1が最初にproduct_id_1と3番目に表示されるのはなぜかわかりませんproduct_id_2の場合。

3
Justin Cave

問題のステートメントを正しく理解している場合は、世代別データを処理する方法が必要です(つまり、テーブルには、日付に依存する各provider_id/product_idペアの複数の行が含まれています)。その場合は、date_price_effective値が今日以下の製品の最新の価格を探しています。このタイプの状況は、SQL副選択を使用して簡単に処理できます。

 SELECT 
   provider_id, product_id, price, date_price_effective 
 FROM 
   price_table a 
 WHERE 
   date_price_effective = 
     (
       SELECT 
         MAX(date_price_effective) 
       FROM 
         price_table b 
       WHERE 
         b.provider_id = a.provider_id AND 
         b.product_id = a.product_id AND
         b.date_price_effective <= NOW() 
     );

価格は、クエリが実行された日付以下の最大のdate_price_effective値を持つ限り有効です。今日よりも大きいdate_price_effective値は、将来の発効日です。上記のコードは、クエリが実行された日付に最も近いが遅くないdate_price_effective値を持つ各provider_id/product_idペアの行データを返します。ソリューションは、価格を有効な日付範囲に自動的に囲みます。このテーブルの主キーは、トリプル{provider_id、product_id、date_price_effective}です。

3
bit-twiddler