我有一张桌子,里面有这样的桌子。
Month-----Book_Type-----sold_in_Dollars
Jan----------A------------ 100
Jan----------B------------ 120
Feb----------A------------ 50
Mar----------A------------ 60
Mar----------B------------ 30
等等
我必须根据过去2个月的销售额计算每月的预期销售额和预订类型。 因此对于March和A型,它将是(100 + 50)/ 2 = 75 3月和B型是120/1,因为没有2月的数据。
我试图使用滞后函数,但由于几行中缺少数据,因此无法正常工作。
有关于此的任何想法吗?
答案 0 :(得分: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
但是这会占用前两个数据点,如果缺少行,则不一定是前两个月。
你可以用延迟来解决这个问题,但这会有点复杂。
答案 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
(假设Month列实际上不包含JAN或FEB,而是真实的,可订购的日期。)
答案 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
答案 3 :(得分:0)
分区外连接可以帮助创建缺少的数据。创建一组月份,并按月将这些值连接到每一行,并为每种书籍类型执行一次连接。我在这个例子中创建了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