我在表格中有月份和值列,例如
Month Value Market
2010/01 100 1
2010/02 200 1
2010/03 300 1
2010/04 400 1
2010/05 500 1
2010/01 100 2
2010/02 200 2
2010/03 300 2
2010/04 400 2
2010/05 500 2
我想要做的是使用(月份(n-1)中的值+月份(n)中的值)/ 2 =月份n中的值来获取新的月份和值组合,此计算也基于市场列,按市场编号分组。因此,对于上面的示例,新月份和值组合应为
Month Value Market
2010/01 null 1
2010/02 (100+200)/2 1
2010/03 (200+300)/2 1
2010/04 (300+400)/2 1
2010/05 (400+500)/2 1
2010/01 null 2
2010/02 (100+200)/2 2
2010/03 (200+300)/2 2
2010/04 (300+400)/2 2
2010/05 (400+500)/2 2
您知道如何在Oracle中实现它吗?谢谢!
答案 0 :(得分:5)
如果您的数据没有差距,可以使用LAG
:
SQL> WITH DATA AS (
2 SELECT DATE '2010-01-01' mon, 100 val FROM dual UNION ALL
3 SELECT DATE '2010-02-01' mon, 200 val FROM dual UNION ALL
4 SELECT DATE '2010-03-01' mon, 300 val FROM dual UNION ALL
5 SELECT DATE '2010-04-01' mon, 400 val FROM dual UNION ALL
6 SELECT DATE '2010-05-01' mon, 500 val FROM dual
7 )
8 SELECT mon, (LAG(val) OVER (ORDER BY mon) + val) / 2 avg_val FROM DATA;
MON AVG_VAL
----------- ----------
01/01/2010
01/02/2010 150
01/03/2010 250
01/04/2010 350
01/05/2010 450
但是,如果存在差距,结果可能与您的预期不符。在这种情况下,您可以使用自联接或缩小窗口子句:
SQL> WITH DATA AS (
2 SELECT DATE '2010-01-01' mon, 100 val FROM dual UNION ALL
3 SELECT DATE '2010-02-01' mon, 200 val FROM dual UNION ALL
4 SELECT DATE '2010-03-01' mon, 300 val FROM dual UNION ALL
5 /* gap ! */
6 SELECT DATE '2010-05-01' mon, 400 val FROM dual UNION ALL
7 SELECT DATE '2010-06-01' mon, 500 val FROM dual
8 )
9 SELECT mon, (first_value(val)
10 OVER (ORDER BY mon
11 RANGE BETWEEN INTERVAL '1' MONTH PRECEDING
12 AND INTERVAL '1' MONTH PRECEDING)
13 + val) / 2 avg_val
14 FROM DATA;
MON AVG_VAL
----------- ----------
01/01/2010
01/02/2010 150
01/03/2010 250
01/05/2010
01/06/2010 450
答案 1 :(得分:3)
这样做:
SQL> select month,
2 (value+lag(value) over (order by month))/2 as value
3* from t1
MONTH VALUE
---------- ----------
2010/01
2010/02 150
2010/03 250
2010/04 350
2010/05 450
5 rows selected.