2010-11-23 19 views
2

私はこのようなテーブルを持っています。ラグSQLコマンドの代わりに

Month-----Book_Type-----sold_in_Dollars 
Jan----------A------------ 100 
Jan----------B------------ 120 
Feb----------A------------ 50 
Mar----------A------------ 60 
Mar----------B------------ 30 

ので、私は最後の2ヶ月間の売上高に基づいて、各月とブックタイプの予想売上高を計算しなければなりません。 3月とタイプAの場合は、(100 + 50)/ 2 = 75 3月とタイプBの場合は、2月のデータがないので120/1です。

私はラグ関数を使用しようとしていましたが、いくつかの行にデータがないので機能しませんでした。

これに関するご意見はありますか?

答えて

0

私の知る限りでは、あなたが)(LAGにデフォルト値を与えることができます:

SELECT Book_Type, 
     (lag(sold_in_Dollars, 1, 0) OVER(PARTITION BY Book_Type ORDER BY Month) + lag(sold_in_Dollars, 2, 0) OVER(PARTITION BY Book_Type ORDER BY Month))/2 AS expected_sales 
    FROM your_table 
GROUP BY Book_Type 

(月列が本当にJANや2月が、実際、注文可能な日付が含まれていないと仮定。)

0

何(SQL Serverの構文を許すが、あなたのアイデアを得る)のようなものについて:

Select Book_type, AVG(sold_in_dollars) 
from MyTable 
where Month in (Month(DATEADD('mm'-1,GETDATE)),Month(DATEADD('mm'-2,GETDATE))) 
group by booktype 
+0

彼は120/1を望んでいますが、(120 + 0)/ 2は愚かです。 – milan

+0

の値を差し込み、それを実行します。 – SteveCav

+0

私が知っている限り、averageはnullを無視するので、2つの行を平均して1つの値がnullの場合、1で割るだけです。 –

1

それは欠損値を無視することを計画しているので、これはおそらく動作するはずです。現時点ではそれをテストするためのデータベースを持っていないが、それ他は午前中に行く与える

select 
    month, 
    book_type, 
    sold_in_dollars, 
    avg(sold_in_dollars) over (partition by book_type order by month 
    range between interval '2' month preceding and interval '1' month preceding) as avg_sales 
from myTable; 

ソートの月が日付データ型があり、でソートすることができます...それだけだ場合と仮定し、このテキスト文字列を入力すると、別のものが必要になります。

通常はrows between 2 preceding and 1 precedingを使用できますが、行が見つからない場合は前の2つのデータポイントが必要で、必ずしも前の2か月間である必要はありません。

あなたは遅れを取り除くことができますが、もう少し複雑になるでしょう。

+0

+1 - 私はbook_typeではなくmonthで分割するべきだと思います。ちょうど意見... – Art

0

パーティション外部結合は、欠落しているデータを作成するのに役立ちます。月のセットを作成し、その値を月ごとに各行に結合し、各ブックタイプに対して1回ずつ結合を実行します。私はこの例で1月から4月の月を作成しました:

with test_data as 
(
    select to_date('01-JAN-2010', 'DD-MON-YYYY') month, 'A' book_type, 100 sold_in_dollars from dual union all 
    select to_date('01-JAN-2010', 'DD-MON-YYYY') month, 'B' book_type, 120 sold_in_dollars from dual union all 
    select to_date('01-FEB-2010', 'DD-MON-YYYY') month, 'A' book_type, 50 sold_in_dollars from dual union all 
    select to_date('01-MAR-2010', 'DD-MON-YYYY') month, 'A' book_type, 60 sold_in_dollars from dual union all 
    select to_date('01-MAR-2010', 'DD-MON-YYYY') month, 'B' book_type, 30 sold_in_dollars from dual 
) 
select book_type, month, sold_in_dollars 
    ,case when denominator = 0 then 'N/A' else to_char(numerator/denominator) end expected_sales 
from 
(
    select test_data.book_type, all_months.month, sold_in_dollars 
    ,count(sold_in_dollars) over 
     (partition by book_type order by all_months.month rows between 2 preceding and 1 preceding) denominator 
    ,sum(sold_in_dollars) over 
     (partition by book_type order by all_months.month rows between 2 preceding and 1 preceding) numerator 
    from 
    (
     select add_months(to_date('01-JAN-2010', 'DD-MON-YYYY'), level-1) month from dual connect by level <= 4 
    ) all_months 
    left outer join test_data partition by (test_data.book_type) on all_months.month = test_data.month 
) 
order by book_type, month