获取最近7天的平均值

时间:2015-01-23 01:53:13

标签: sql postgresql amazon-redshift

我正在攻击一个问题,我有一个日期范围的值。我想通过对它们进行平均并将日期列重新分配为相对于过去7天来合并表格中的行。我缺乏SQL经验,可以使用一些帮助。谢谢你看看!!

E.g。 7行包含日期和值。

UniqueId    Date      Value
........    ....     .....
  a       2014-03-20   2
  a       2014-03-21   2
  a       2014-03-22   3
  a       2014-03-23   5
  a       2014-03-24   1
  a       2014-03-25   0
  a       2014-03-26   1

结果行

UniqueId    Date      AvgValue
........    ....      ........
  a       2014-03-26   2

首先,我甚至不确定这是可能的。我正试图用手头的数据来解决问题。我想可能使用带有分区的框架窗口将日期滚动到具有平均结果的日期,但我不确定如何在SQL中说出来。

4 个答案:

答案 0 :(得分:0)

也许类似于SELECT AVG(Value) AS 'AvgValue' FROM tableName WHERE Date BETWEEN dateStart AND dateEnd的内容这将使您获得这些日期之间的平均值,并且您已经拥有dateEnd,因此您可以使用该结果来创建您正在寻找的行。

答案 1 :(得分:0)

对于SQL Server,您可以按照以下方法操作。试试这个

<强> 1。对于每周价值的平均值

SET DATEFIRST 4
;WITH CTE AS
(
    SELECT *,
    DATEPART(WEEK,[DATE])WK,
    --Find last day in that week 
    ROW_NUMBER() OVER(PARTITION BY UNIQUEID,DATEPART(WEEK,[DATE]) ORDER BY [DATE] DESC) RNO,
    -- Find average value of that week
    AVG(VALUE) OVER(PARTITION BY UNIQUEID,DATEPART(WEEK,[DATE])) AVGVALUE
    FROM DATETAB
)
SELECT UNIQUEID,[DATE],AVGVALUE
FROM CTE
WHERE RNO=1

<强> 2。过去7天的价值平均值

    DECLARE @DATE DATE = '2014-03-26'

    ;WITH CTE AS
    (
        SELECT UNIQUEID,[DATE],VALUE,@DATE CURRENTDATE 
        FROM DATETAB
        WHERE [DATE] BETWEEN DATEADD(DAY,-7,@DATE) AND @DATE
    )
    SELECT UNIQUEID,CURRENTDATE [DATE],AVG(VALUE) AVGVALUE
    FROM CTE
    GROUP BY UNIQUEID,CURRENTDATE

答案 2 :(得分:0)

对于PostgreSQL,窗口函数可能就是你想要的:

DROP TABLE IF EXISTS some_data;

CREATE TABLE some_data (unique_id text, date date, value integer);

INSERT INTO some_data (unique_id, date, value) VALUES 
 ( 'a', '2014-03-20', 2),
 ( 'a', '2014-03-21', 2),
 ( 'a', '2014-03-22', 3),
 ( 'a', '2014-03-23', 5),
 ( 'a', '2014-03-24', 1),
 ( 'a', '2014-03-25', 0),
 ( 'a', '2014-03-26', 1),
 ( 'a', '2014-03-27', 3);

WITH avgs AS (
    SELECT unique_id, date, 
        avg(value) OVER w AS week_avg,
        count(value) OVER w AS num_days
    FROM some_data
    WINDOW w AS (
        PARTITION BY unique_id 
        ORDER BY date 
        ROWS BETWEEN 6 PRECEDING AND CURRENT ROW))
SELECT unique_id, date, week_avg
FROM avgs
WHERE num_days=7 

结果:

 unique_id |    date    |      week_avg      
-----------+------------+--------------------
 a         | 2014-03-26 | 2.0000000000000000
 a         | 2014-03-27 | 2.1428571428571429

问题包括:

  1. 如果缺少前6天的一天会怎样?我们想要添加它并将其计为零吗?
  2. 如果你加一天会怎么样?代码的结果是否符合您的要求(7天平均值)?

答案 3 :(得分:0)

我将以下作为样本

CREATE TABLE some_data1 (unique_id text, date date, value integer);

INSERT INTO some_data1 (unique_id, date, value) VALUES 
 ( 'a', '2014-03-20', 2),
 ( 'a', '2014-03-21', 2),
 ( 'a', '2014-03-22', 3),
 ( 'a', '2014-03-23', 5),
 ( 'a', '2014-03-24', 1),
 ( 'a', '2014-03-25', 0),
 ( 'a', '2014-03-26', 1),
 ( 'b', '2014-03-01', 1),
 ( 'b', '2014-03-02', 1),
 ( 'b', '2014-03-03', 1),
 ( 'b', '2014-03-04', 1),
 ( 'b', '2014-03-05', 1),
 ( 'b', '2014-03-06', 1),
 ( 'b', '2014-03-07', 1)

选项A: - 使用PostgreSQL特定函数WITH

with cte as (
select unique_id
      ,max(date) date 
from some_data1 
group by unique_id
)
select max(sd.unique_id),max(sd.date),avg(sd.value)
from some_data1 sd inner join cte using(unique_id)
where sd.date <=cte.date 
group by cte.unique_id
limit 7 

> SQLFIDDLE DEMO


选项B: - 在PostgreSQL和MySQL中工作

select max(sd.unique_id)
      ,max(sd.date)
      ,avg(sd.value) 
from (
      select unique_id
            ,max(date) date 
      from some_data1 
      group by unique_id
     ) cte inner join some_data1 sd using(unique_id)
where sd.date <=cte.date 
group by cte.unique_id
limit 7 

> SQLFDDLE DEMO