Php 计算5天移动平均值-如果日期之间存在差距,则将值设置为0。

Php 计算5天移动平均值-如果日期之间存在差距,则将值设置为0。,php,mysql,moving-average,Php,Mysql,Moving Average,我在计算5天移动平均线。一切都很顺利,除了日期之间有间隔。当存在间隙时,缺失日期(-s)的值应设置为零,以显示正确的移动平均值 这是我的表格(订单总数),您可以看到没有2013年1月7日的日期,这导致了问题: orders_id value date 1 199 1/1/13 0:00 2 199 1/2/13 0:00 3 199 1/3/13 0:00 4 199

我在计算5天移动平均线。一切都很顺利,除了日期之间有间隔。当存在间隙时,缺失日期(-s)的值应设置为零,以显示正确的移动平均值

这是我的表格(订单总数),您可以看到没有2013年1月7日的日期,这导致了问题:

orders_id    value    date
1            199      1/1/13 0:00
2            199      1/2/13 0:00
3            199      1/3/13 0:00
4            199      1/4/13 0:00
5            249      1/5/13 0:00
6            199      1/6/13 0:00
7            199      1/8/13 0:00
8            199      1/9/13 0:00
9            199      1/10/13 0:00
10           199      1/11/13 0:00
11           199      1/12/13 0:00
12           199      1/13/13 0:00
如果缺失日期1/7/13的值设置为零,则正确的5天移动平均线(我正在寻找)为:

这是我正在使用的代码,当日期之间存在差距时,它不会显示正确的移动平均值:

    SELECT ot1.value, ot1.date,
    (SELECT SUM(ot2.value) / COUNT(ot2.value)
    FROM orders_total AS ot2 WHERE DATEDIFF(ot1.date, ot2.date) BETWEEN 0 AND 4) AS '5dayMovingAvg'
    FROM orders_total AS ot1 ORDER BY ot1.date";

如果您知道它总是5天,为什么要除以计数(ot2.value)?除非您试图处理边缘情况,否则在这种情况下,请以与正常情况不同的方式处理边缘情况。

尝试此查询:

SELECT ot1.value, ot1.date,
            (    SELECT SUM(ot2.value) / COUNT(ot2.value)
            FROM (

     select * from orders_total union
        (SELECT 0 as order_id,0 as `value`,DATE(r1.date) + INTERVAL 1 DAY AS missing_date
        FROM orders_total r1
        LEFT OUTER JOIN orders_total r2 ON DATE(r1.date) = DATE(r2.date) - INTERVAL 1 DAY 
        WHERE r2.date IS NULL )

) AS ot2 WHERE DATEDIFF(ot1.date, ot2.date) BETWEEN 0 AND 4) AS '5dayMovingAvg'
            FROM (

    select * from orders_total union
        (SELECT 0 as order_id,0 as `value`,DATE(r1.date) + INTERVAL 1 DAY AS missing_date
        FROM orders_total r1
        LEFT OUTER JOIN orders_total r2 ON DATE(r1.date) = DATE(r2.date) - INTERVAL 1 DAY 
        WHERE r2.date IS NULL )

) 

        AS ot1 ORDER BY ot1.date
基本上,我所做的是从您的查询中替换orders\u total tabel,并替换为

select * from orders_total union
        (SELECT 0 as order_id,0 as `value`,DATE(r1.date) + INTERVAL 1 DAY AS missing_date
        FROM orders_total r1
        LEFT OUTER JOIN orders_total r2 ON DATE(r1.date) = DATE(r2.date) - INTERVAL 1 DAY 
        WHERE r2.date IS NULL )
这个查询,我可以把它放在视图中,但mysql视图不支持视图中的union可能是一个bug

注意:这还将包括一个额外的日期行,您可以使用max(date)将其排除在外

上述查询的结果:

199 2013-01-01 00:00:00 199.0000
199 2013-01-02 00:00:00 199.0000
199 2013-01-03 00:00:00 199.0000
199 2013-01-04 00:00:00 199.0000
249 2013-01-05 00:00:00 209.0000
199 2013-01-06 00:00:00 209.0000
0   2013-01-07 00:00:00 169.2000
199 2013-01-08 00:00:00 169.2000
199 2013-01-09 00:00:00 169.2000
199 2013-01-10 00:00:00 159.2000
199 2013-01-11 00:00:00 159.2000
199 2013-01-12 00:00:00 199.0000
199 2013-01-13 00:00:00 199.0000
0   2013-01-14 00:00:00 159.2000

考虑构建一个包含所有日期的日历实用程序表,然后加入您的表,谢谢!但是,在尝试您的查询时,我收到了错误消息:1222-使用的SELECT语句的列数不同,这是您的
orders\u total
表的架构??将此
SELECT*from orders\u total union
替换为查询中的
SELECT order\u id、value、date from orders\u total union
,然后重试。希望这有帮助。
199 2013-01-01 00:00:00 199.0000
199 2013-01-02 00:00:00 199.0000
199 2013-01-03 00:00:00 199.0000
199 2013-01-04 00:00:00 199.0000
249 2013-01-05 00:00:00 209.0000
199 2013-01-06 00:00:00 209.0000
0   2013-01-07 00:00:00 169.2000
199 2013-01-08 00:00:00 169.2000
199 2013-01-09 00:00:00 169.2000
199 2013-01-10 00:00:00 159.2000
199 2013-01-11 00:00:00 159.2000
199 2013-01-12 00:00:00 199.0000
199 2013-01-13 00:00:00 199.0000
0   2013-01-14 00:00:00 159.2000