2

次の形式のデータがあります。

date        fruit
======================
1-jan-14    orange
3-jan-14    orange
1-may-14    orange
2-may-14    apple
3-may-14    apple
1-aug-14    pineapple
2-aug-14    apple

過去 6 か月間に最も購入された果物を表す列を追加したいと思います。したがって、上記の例では次のようになります。

date        fruit       most_purchased_6_months
=======================================
1-jan-14    orange      orange
3-jan-14    orange      orange
1-may-14    orange      orange
2-may-14    apple       orange
3-may-14    apple       orange
1-aug-14    pineapple   apple
2-aug-14    apple       apple

分析関数を使用してみましたが、到達した最高の結果は、過去 6 か月間に同じ果物 (同じ行から) が購入された回数を示すことです。前)」。

私の主な問題は、自己結合を使用すると問題を簡単に解決できることですが、これは約 2,000 万行のデータを含むテーブルであるため、データベースで実行するには数時間かかります。指示や助けをいただければ幸いです。

4

1 に答える 1

1

これはあなたの基本的なクエリです:

select date, fruit,
       count(*) over (partition by fruit order by date range 180 preceding) as NumberPurchased
from data;

サブクエリと でこれを行うことができると思いますfirst_value()

select date, fruit,
       first_value(fruit) over (order by NumberPurchased desc range 180 preceding)
from (select date, fruit,
             count(*) over (partition by fruit order by date range 180 preceding) as NumberPurchased
      from data d
     ) d;

私は答えを残していますが、前の6か月の各行でカウントが変化するため、上記は機能しません.

編集:

ここでは、まったく異なるアプローチを示します。日ごと、果物ごとに累積合計を一時テーブルに計算します。次に、そのテーブルにインデックスを付けて結合し、次を使用して最も一般的な果物を取得しますkeep

create table FruitCountCume as
    select f.fruit, da.date, count(*) over (partition by f.fruit order by d.date) as cumecnt
    from (select distinct fruit from data) f cross join
         (select distinct date from data) d left outer join
         data da
         on f.fruit = da.fruit and f.date = da.date;

create index on FruitCountCume(fruit, date);

select d1.date, d1.fruit,
       max(fruit) keep (dense_rank first order by d1.cumecnt - coalesce(d2.cumecnt, 0) desc) as MostCommon
from FruitCountCume d1 left outer join
     FruitCountCume d2
     on d1.date = d2.date + 180
group by d1.date;

フルクロス結合は必要ないかもしれません。left joinより効率的にするための利便性としてあります。

于 2014-08-24T10:59:21.680 に答える