0

私はこの問題について数時間熟考してきましたが、運が悪かったので、SOの人々が助けてくれるかもしれません:)

店舗での処理量に関するデータを含むテーブルがあります。以下に示す最初の 3 つの列は、そのテーブルからクエリできます。私がやろうとしているのは、基本的にストアが $150 以上を処理したかどうかに関するフラグである 4 番目の列を追加することです。そうであれば、対応する日付を表示します。これが機能する方法は、ストアが $150 を超えた最初のインスタンスが表示される日付です。その後の処理量は、最初のインスタンスがアクティブ化された日付に達した後はカウントされません。たとえば、店舗 4 の場合、有効化された日付のインスタンスは 1 つだけです。

store_id  sales_volume   date        activated_date
----------------------------------------------------    
2         5              03/14/2012    
2         125            05/21/2012   
2         30             11/01/2012   11/01/2012    
3         100            02/06/2012
3         140            12/22/2012   12/22/2012
4         300            10/15/2012   10/15/2012
4         450            11/25/2012
5         100            12/03/2012

この 4 番目の列を構築する方法についての洞察はありますか? 前もって感謝します!

4

2 に答える 2

1

バリアント1

LEFT JOIN店舗あたり150ドルの制限を超える最初のデートを計算するテーブルにできます。

SELECT t.*, b.activated_date
FROM   tbl t
LEFT   JOIN (
   SELECT store_id, min(thedate) AS activated_date
   FROM  (
      SELECT store_id, thedate
            ,sum(sales_volume) OVER (PARTITION BY store_id
                                     ORDER BY thedate) AS running_sum
      FROM   tbl
      ) a
   WHERE  running_sum >= 150
   GROUP  BY 1
   ) b ON t.store_id = b.store_id AND t.thedate = b.activated_date
ORDER  BY t.store_id, t.thedate;

初日の計算は2つのステップで行う必要があります。これは、現在の合計を累積するウィンドウ関数を別ので適用する必要があるためSELECTです。

バリアント2

の代わりに別のウィンドウ関数LEFT JOIN。5月は速くないかもしれません。でテストしEXPLAIN ANALYZEます。

SELECT *
      ,CASE WHEN running_sum >= 150 AND thedate = first_value(thedate)
               OVER (PARTITION BY store_id, running_sum >= 150 ORDER BY thedate)
       THEN thedate END AS activated_date
FROM  (
   SELECT *
         ,sum(sales_volume)
              OVER (PARTITION BY store_id ORDER BY thedate) AS running_sum
   FROM   tbl
   ) b
ORDER  BY store_id, thedate;

->sqlfiddleは両方を示しています。

于 2013-02-06T23:05:38.317 に答える
1

ソリューションは、累積売上を計算することから始まります。次に、累積売上高が最初に $150 レベルを通過したときの有効化日のみが必要です。これは、現在の販売額を追加すると、累積額がしきい値を超えたときに発生します。次のcase式はこれを処理します。

select t.store_id, t.sales_volume, t.date,
       (case when 150 > cumesales - t.sales_volume and 150 <= cumesales
             then date
        end) as ActivationDate
from (select t.*,
             sum(sales_volume) over (partition by store_id order by date) as cumesales
      from t
     ) t

累積合計をサポートしていない古いバージョンの Postgres を使用している場合は、次のようなサブクエリを使用して累積売上を取得できます。

(select sum(sales_volume) from t t2 where t2.store_id = t.store_id and t2.date <= t.date) as cumesales
于 2013-02-06T22:49:29.620 に答える