获取最近 7 天的平均值

Get average of last 7 days

我正在解决一个问题,其中我有一个日期范围的值。我想合并我的 table 中的行,方法是对它们进行平均并将日期列重新分配为相对于过去 7 天。我的 SQL 经验不足,需要一些帮助。感谢您的关注!!

例如 包含日期和值的 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

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

也许与 SELECT AVG(Value) AS 'AvgValue' FROM tableName WHERE Date BETWEEN dateStart AND dateEnd 类似的东西会得到这些日期之间的平均值,并且您已经有了 dateEnd,因此您可以使用该结果来创建您要查找的行。

对于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

对于 PostgreSQL,window 函数可能就是您想要的:

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. 如果缺少前六天中的一天会怎样?我们要添加它并将其计为零吗?
  2. 如果你加一天会怎样?代码的结果是否高于您想要的结果(滚动 7 天平均值)?

以下为样本

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