2012-01-21 329 views
0

製品と顧客ごとに毎週、毎月の販売データを動的に更新する必要があります。これらは、製品の販売中に更新およびチェックする必要があります。さまざまな理由から、ストアドプロシージャやマテリアライズドビューを使用することができません。アプリケーションのすべてを読み込み、メモリ内のすべてを変更してから更新します。結果をコミットする)。週単位と月単位の集計をOracleに保存

期間中売上を保持するための最適なテーブル構造は何ですか?

  • 開始日と終了日、またはタイプと開始日をピリオドタイプ(M、W)で保存しますか?
  • 日付フィールドとcharを使用するか、文字列にコード化する( 'M201201'/'W201248')
  • 売上と期間を2つのテーブルに正規化するか、

現在の週次(xorまたは月次)期間/顧客/記事の販売を選択しますが、更新はしません。顧客/記事の週間および月間の更新を選択します。

答えて

1

該当する期間の開始日と終了日の両方を行に格納すると、検索クエリは、少なくとも今日のような単一の日付に基づく検索クエリよりはるかに簡単になります。これは、アクセスの非常に典型的なモードです。特定の日付に発生するビジネストランザクション(特定の販売など)の観点から物事を見ている可能性が高いからです。

where @date_of_interest >= start_date and @date_of_interest <= end_dateと言うのは非常に直接的で簡単です。他の組み合わせでは、クエリに移動する前に、またはクエリ自体の中で、コードで日付演算を行う必要があります。

タイプコード(M、W)と開始日と終了日の両方を保持すると、冗長性が導入されます。ただし、データの取得を容易にするために、この冗長性を導入することもできます。これは:where @date_of_interest >= start_date and @date_of_interest <= end_date and range_type='M'も非常に直接的でシンプルです。

すべての非正規化と同様に、この冗長性を管理するコントロールがあることを確認する必要があります。

+0

おかげで、日付計算についての良い点 - あまりにも私の最初の懸念でした。残念ながら、私はエントリを作成するときに正しい日付を入れなければならないので、私はそれを避けることができません - 私たちのORMフレームワークのためにTRUNC(@ date_of_interest、 'IW')を単に使うことはできません。 –

0

同じ構造の2つの異なるテーブルに週単位と月単位の集計を格納するために、正規化されたスキーマを使用することをお勧めします。私はあなたがしようとしているクエリの種類はわかりませんが、これで検索が簡単になると思います(正しい方法で済ませれば!!!)。

おそらく、このサンプルのようなもの

product_prices (
    prod_code, 
    price, 
    date_price_begin 
); 

sales (
    prod_code, 
    customer_code, 
    sale_date 
); 


<aggregate-week> 
select trunc(sale_date,'w') as week, 
    prod_code, 
    customer_code, 
    sum(price) keep (dense_rank first order by date_price_start) as price 
from sales 
    natural join product_prices 
where sale_date > date_from 
group by trunc(sale_date,'iw'), 
    prod_code, 
    customer_code 
/

<aggregate-month> 
select trunc(sale_date,'m') as month, 
    prod_code, 
    customer_code, 
    sum(price) keep (dense_rank first order by date_price_start) as price 
from sales 
    natural join product_prices 
where sale_date > date_from 
group by trunc(sale_date,'m'), 
    prod_code, 
    customer_code 
/
+0

私は実際のSQL集計を行うことはできません。一度(ビューを使用して)試してみましたが、それほど高速ではありませんでした(すべての注文ラインの集計された売上データをチェックする必要があります)。また、私は期間全体で販売された実際の数量に興味があります。期間中の価格ではありません。インデックスを持つ1つのテーブル、または2つのパーティションを持つ単一のテーブルの代わりに、2つのテーブルを使用する利点は何ですか? –

+0

私はそれらのクエリがどのように遅くなることが想像できません!彼らが使用するテーブルはそれほど大きくなくてはならず(各行ごとに50バイト未満)、集計テーブルは(毎週/毎月の末尾に新しい行を追加することによって)段階的に構築されます。とにかく私はその事件をテストし、私は結果を私のポストに更新します。 –

+0

私はあなたが誤解していると思う、週が終わってから毎週の集計は必要ありません。私は週にそれを必要とします(在庫の一部として)。つまり、水曜日13:45に顧客100000の商品123456の販売を処理しているときは、月曜日の00:00から水曜日の取引の開始まで商品の合計販売額が必要になります。私が顧客に製品を販売するたびに、私は販売データ上で 'SELECT .. GROUP BY'をしなければならないだけで、データベースは維持できなくなります。このため、各販売後に集計の増分更新を行う必要があります。 –