列'date'中有多个日期。 “价值”列中的数字。在每个具体的“日期”之前和之后拉出3天的“价值”总和

时间:2016-02-20 22:49:35

标签: sql oracle

Oracle中的SQL:

数据集示例:

Search_date  Value
01-Feb-2016      5
02-Feb-2016      4
03-Feb-2016      9
04-Feb-2016     10 
05-Feb-2016     12
06-Feb-2016     10
07-Feb-2016      7

所以......如果我设置了search_date = '04 -Feb-2016'的where条件,它将返回以下内容:

Search_date,Before_Period,After_Period,

04-Feb-2016 18 (9 + 4 + 5)......, 29 (10 + 12 + 7)< / p>

但我想在每个不同的日期拉这个

3 个答案:

答案 0 :(得分:3)

使用SUM() analytical (windowed) function

Oracle安装程序

CREATE TABLE DataSet ( Search_date, Value ) AS
SELECT DATE '2016-02-01',  5 FROM DUAL UNION ALL
SELECT DATE '2016-02-02',  4 FROM DUAL UNION ALL
SELECT DATE '2016-02-03',  9 FROM DUAL UNION ALL
SELECT DATE '2016-02-04', 10 FROM DUAL UNION ALL
SELECT DATE '2016-02-05', 12 FROM DUAL UNION ALL
SELECT DATE '2016-02-06', 10 FROM DUAL UNION ALL
SELECT DATE '2016-02-07',  7 FROM DUAL;

<强>查询

SELECT  search_date,
        COALESCE(
          SUM( value ) OVER (
            ORDER BY Search_date
            ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING
          ),
          0
        ) AS before_period,
        COALESCE(
          SUM( value ) OVER (
            ORDER BY Search_date
            ROWS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING
          ),
          0
        ) AS after_period
FROM    DataSet;

<强>输出

SEARCH_DATE BEFORE_PERIOD AFTER_PERIOD
----------- ------------- ------------
01-FEB-16               0           52 
02-FEB-16               5           48 
03-FEB-16               9           39 
04-FEB-16              18           29 
05-FEB-16              28           17 
06-FEB-16              40            7 
07-FEB-16              50            0 

如果您只希望在之前/之后的3天内将UNBOUNDED更改为3

答案 1 :(得分:2)

尝试aggregate (windowing clause)个功能:

select dt, 
sum(val) over(order by dt  rows between 3 preceding and 1 preceding) as prev,  
sum(val) over(order by dt  rows between 1 following and 3 following) as next 
from t order by dt;

输出:

DT          PREV    NEXT
02/01/2016          18
02/01/2016  5       23
02/02/2016  10      31
02/03/2016  14      32
02/04/2016  18      29
02/05/2016  23      17
02/06/2016  31      7
02/07/2016  32  

答案 2 :(得分:0)

可能不是最高性能的解决方案(未经过oracle测试,但应该没有区别):

select a.dat search_date, (select sum(b.val) from john b where b.dat < a.dat) before_period, (select sum(c.val) from john c where c.dat > a.dat) after_period from john a;
+-------------+---------------+--------------+
| search_date | before_period | after_period |
+-------------+---------------+--------------+
| 2016-02-01  |          NULL |           52 |
| 2016-02-02  |             5 |           48 |
| 2016-02-03  |             9 |           39 |
| 2016-02-04  |            18 |           29 |
| 2016-02-05  |            28 |           17 |
| 2016-02-06  |            40 |            7 |
| 2016-02-07  |            50 |         NULL |
+-------------+---------------+--------------+

还在考虑尝试多个自我加入,但是......