1

過去 1 年間で月間販売台数 10,000 台を超えた店舗の月間販売台数を少なくとも 6 か月間引っ張ろうとしています。私のソース販売テーブルは毎日です。したがって、すべての店舗のすべての月の売上を計算し、次に 10,000 ユニットを 6 回超えた店舗を特定し、その店舗のリストをクエリのフィルターとして使用して、フィルター処理された店舗のすべての月を計算します。

sum(units_sold)したがって、基本的に、同じクエリで同じ集計計算を 2 回行っています。

select
    store_location,
    sales_date - extract(day from sales_date) + 1 as sales_month,
    sum(units_sold) as monthly_sales,   /* I already calculated this!  How to re-use? */
    case when sum(units_sold) > 10000 then 1 else 0 end as exceeded_10000 

from
    daily_sales

where
    sales_date between '2012-01-01' and '2012-12-31' and
    store_location in (
        select
            store_location
        from (
                select
                    store_location,
                    sales_date - extract(day from sales_date) + 1 as sales_month,
                    case when sum(units_sold) > 10000 then 1 else 0 end as exceeded_10000   /* evaluated per month, per store */
                from
                    daily_sales
                where
                    sales_date between '2012-01-01' and '2012-12-31'
                group by
                    store_location,
                    sales_date - extract(day from sales_date) + 1
        ) a
        group by
            store_location
        having
            sum(exceeded_10000) > 6   /* which stores had 6 months over 10000 ? */ 
    )

group by
    store_location,
    sales_date - extract(day from sales_date) + 1

これは効率が悪いようですsum(units_sold)。内部 (フィルタリング) クエリで既に月ごとに計算していますが、これらの月ごとの合計を再利用する方法がわかりません。クエリ b は、売上が 10,000 を超えた月の数を合計しているため、必要に応じて月ごとにグループ化されていないことに注意してください。これは、私がタイトルで言及している集計の集計です。

Teradata は PIVOT 関数をサポートしていません。私は、CASE WHEN を大量に使用してピボットをエミュレートし、毎月 1 行をチェックすることは避けたいと考えています。

このクエリをより効率的にする方法はありますか? 内部クエリで既に計算した月間売上合計を再利用するには? Teradata の代わりに別の RDBMS プラットフォームで簡素化できますか? ありがとうございました。

4

1 に答える 1

3

あなたのクエリは、あなたが望むことをしていないようです。外部クエリは月ごとにグループ化されていますが、これは必要ありません。

次のクエリは、売上が 10,000 を超える 6 か月以上の場所を返します。

select store_location, sum(month_units_sold) as totalunits,
        sum(exceeded_10000) as months_over_10000
from (select store_location,
             sales_date - extract(day from sales_date) + 1 as sales_month,
             sum(units_sold) as month_units_sold
             (case when sum(units_sold) > 10000 then 1 else 0 end) as exceeded_10000   /* evaluated per month, per store */
      from daily_sales
      where sales_date between '2012-01-01' and '2012-12-31'
      group by store_location, sales_date - extract(day from sales_date) + 1
    ) t
group by store_location
having sum(exceeded_10000) >= 6

各店舗に関する月ごとの情報が必要な場合は、ウィンドウ関数を使用して超過した月数を計算します。

select *
from (select t.*,
             SUM(exceeded_10000) over (partition by store_location) s MonthsExceeded10000
      from (select store_location,
                   sales_date - extract(day from sales_date) + 1 as sales_month,
                   sum(units_sold) as month_units_sold
                   (case when sum(units_sold) > 10000 then 1 else 0 end) as exceeded_10000   /* evaluated per month, per store */
            from daily_sales
            where sales_date between '2012-01-01' and '2012-12-31'
            group by store_location, sales_date - extract(day from sales_date) + 1
          ) t
    ) t
where MonthsExceeded10000
于 2013-01-03T02:56:39.970 に答える