2010-11-23 50 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型,它是120/1,因爲沒有2月份的數據。

我試圖使用滯後函數,但它不會工作,因爲有幾行數據丟失。

對此的任何想法?

回答

0

據我所知,你可以給一個缺省值滯後():(假設Month列並沒有真正包含JAN或FEB但真實的,訂購日期)

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 

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 2010-11-23 23:57:14

+0

插入值並運行它。 – SteveCav 2010-11-24 00:16:07

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,但是如果有行丟失,則這將取前兩個數據點,而不一定是前兩個月。

你可以用滯後的方法解決它,但它會更復雜一點。

0

分區外連接可以幫助創建缺失的數據。創建一組月份並將這些值連接到每月的每一行,併爲每種書本類型執行一次連接。我在這個例子中創建了一月到四月的月份:

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