2015-11-17 8 views
0

Я хочу найти скользящую среднюю за последние 30 дней. напримеркак найти скользящую среднюю за все дни за последние 30 дней с пробелом в дате, установленном на 0

Сегодня дата 17/11/15, у меня есть данные только дни

Исходные данные

date   qty  
06/11/15  5  
08/11/15  7  
09/11/15  8  
10/11/15  12  
11/11/15  34  
15/11/15  45  
16/11/15  12  
17/11/15  7  

Найти 30 дневные скользящие средние данные - нужно, чтобы получить movingAvg так же, как в таблице ниже -movingAvg column

date  qty  movingAvg 

17/10/15  0  0 
18/10/15  0  0  
19/10/15  0  0  
20/10/15  0  0  
21/10/15  0  0 
22/10/15  0  0 
23/10/15  0  0 
24/10/15  0  0 
25/10/15  0  0  
26/10/15  0  0  
27/10/15  0  0 
28/10/15  0  0 
29/10/15  0  0 
30/10/15  0  0 
31/10/15  0  0  
01/11/15  0  0  
02/11/15  0  0 
03/11/15  0  0 
04/11/15  0  0  
05/11/15  0  0  
06/11/15  5  0.14  
07/11/15  0  1.4  
08/11/15  7  0.4  
09/11/15  8  0.67  
10/11/15  12  1.06  
11/11/15  34  2.2  
12/11/15  0  2.2  
13/11/15  0  2.2  
14/11/15  0  2.2 
15/11/15  45  3.7  
16/11/15  12  4.1 
17/11/15  7  4.33 

Пожалуйста, помогите мне с запросом mysql для этого или если для этого есть альтернатива.

+0

В среднем это не движение. – Strawberry

+0

'select avg (movingAvg) из таблицы, где date_sub (дата, INTERVAL 30 DAY)' или что-то подобное? –

+0

Я хочу найти moveAvg второго из первой таблицы с любым запросом mysql или программой plsql –

ответ

0

Есть много способов кожи этого кота. Вот один, который использует календарную таблицу со всеми правдоподобными датами (угнетающе небольшой набор данных) ...

CREATE TABLE calendar (dt DATE NOT NULL PRIMARY KEY); 
-- INSERT values for all plausible dates. Lots of tutorials on this. 

CREATE TABLE my_table 
(date DATE NOT NULL 
,qty INT NOT NULL 
,PRIMARY KEY (date) 
); 

INSERT INTO my_table VALUES 
('2015/11/06',5), 
('2015/11/08',7), 
('2015/11/09',8), 
('2015/11/10',12), 
('2015/11/11',34), 
('2015/11/15',45), 
('2015/11/16',12), 
('2015/11/17',7); 


SELECT a.* 
    , AVG(b.qty) average 
    FROM 
    (SELECT c.dt 
      , COALESCE(x.qty,0) qty 
     FROM calendar c 
     LEFT 
     JOIN my_table x 
      ON x.date = c.dt 
     WHERE c.dt BETWEEN (SELECT MAX(date) - INTERVAL 31 DAY FROM my_table) AND (SELECT MAX(date) FROM my_table) 
    ) a 
    JOIN 
    (SELECT c.dt 
      , COALESCE(x.qty,0) qty 
     FROM calendar c 
     LEFT 
     JOIN my_table x 
      ON x.date = c.dt 
     WHERE c.dt BETWEEN (SELECT MAX(date) - INTERVAL 31 DAY FROM my_table) AND (SELECT MAX(date) FROM my_table) 
    ) b 
    ON b.dt <= a.dt 
GROUP 
    BY a.dt; 
+------------+------+---------+ 
| dt   | qty | average | 
+------------+------+---------+ 
| 2015-10-15 | 0 | 0.0000 | 
| 2015-10-16 | 0 | 0.0000 | 
| 2015-10-17 | 0 | 0.0000 | 
| 2015-10-18 | 0 | 0.0000 | 
| 2015-10-19 | 0 | 0.0000 | 
| 2015-10-20 | 0 | 0.0000 | 
| 2015-10-21 | 0 | 0.0000 | 
| 2015-10-22 | 0 | 0.0000 | 
| 2015-10-23 | 0 | 0.0000 | 
| 2015-10-24 | 0 | 0.0000 | 
| 2015-10-25 | 0 | 0.0000 | 
| 2015-10-26 | 0 | 0.0000 | 
| 2015-10-27 | 0 | 0.0000 | 
| 2015-10-28 | 0 | 0.0000 | 
| 2015-10-29 | 0 | 0.0000 | 
| 2015-10-30 | 0 | 0.0000 | 
| 2015-10-31 | 0 | 0.0000 | 
| 2015-11-01 | 0 | 0.0000 | 
| 2015-11-02 | 0 | 0.0000 | 
| 2015-11-03 | 0 | 0.0000 | 
| 2015-11-04 | 0 | 0.0000 | 
| 2015-11-05 | 0 | 0.0000 | 
| 2015-11-06 | 5 | 0.2174 | 
| 2015-11-07 | 0 | 0.2083 | 
| 2015-11-08 | 7 | 0.4800 | 
| 2015-11-09 | 8 | 0.7692 | 
| 2015-11-10 | 12 | 1.1852 | 
| 2015-11-11 | 34 | 2.3571 | 
| 2015-11-12 | 0 | 2.2759 | 
| 2015-11-13 | 0 | 2.2000 | 
| 2015-11-14 | 0 | 2.1290 | 
| 2015-11-15 | 45 | 3.4688 | 
| 2015-11-16 | 12 | 3.7273 | 
| 2015-11-17 | 7 | 3.8235 | 
+------------+------+---------+ 
+0

Это работает, спасибо Strawberry –

+0

Привет, Stawberry, мне нужно улучшение по этому запросу, где во внешнем запросе AVG принимает значения entires до этого дня, но мне нужно взять SUM (значения)/30, где эти значения 'должно быть за последние 30 дней. –

+0

В настоящее время этот запрос присоединяется к 'b.dt <= a.dt'. Теперь вы хотите, чтобы он присоединился к 'b.dt BETWEEN a.dt - INTERVAL 30 DAY AND a.dt' – Strawberry

-2

Попробуйте это ....

SELECT * FROM your_table 
WHERE date >= DATEADD(day,-30, now()) AND date <= now() 

Надеется, что это помогает ..

+0

Что такое getdate()? – Strawberry

+0

getdate(); это функция, которую вы должны сделать для получения даты сервера. в противном случае вы можете ue СЕЙЧАС() –

0

Использования MySQL str_to_date или INTERVAL

select date,qty,avg(qty) from table  
WHERE str_to_date(date,'%d/%m/%y') >= DATE(NOW()) - INTERVAL 30 DAY 
GROUP BY date 
+0

, если есть пробел в датах, тогда этот запрос не работает. –

0

Генерированием диапазона дат, и соединяющий что против исходных данных. Присоединение дважды, один раз, чтобы получить эти дни и один раз, чтобы получить среднее значение за последние 30 дней.

SELECT sub0.aDate, IFNULL(od1.qty, 0), AVG(IFNULL(od2.qty, 0)) 
FROM 
(
    SELECT DATE_SUB(CURRENT_DATE(), INTERVAL (units.a + tens.a * 10) DAY) AS aDate, DATE_SUB(CURRENT_DATE(), INTERVAL ((units.a + tens.a * 10) + 29) DAY) AS prevDate 
    FROM 
    (SELECT 0 a UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) units 
    CROSS JOIN 
    (SELECT 0 a UNION SELECT 1 UNION SELECT 2) tens 
) sub0 
INNER JOIN 
(
    SELECT DATE_SUB(CURRENT_DATE(), INTERVAL (units.a + tens.a * 10) DAY) AS aDate 
    FROM 
    (SELECT 0 a UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) units 
    CROSS JOIN 
    (SELECT 0 a UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5) tens 
) sub1 
ON sub1.aDate BETWEEN sub0.prevDate AND sub0.aDate 
LEFT OUTER JOIN original_data od1 ON od1.`date` = sub0.aDate 
LEFT OUTER JOIN original_data od2 ON od2.`date` = sub1.aDate 
GROUP BY aDate, od1.qty 
ORDER BY aDate 
+0

Исправлено опечатки сейчас, и оно должно давать 30-дневное среднее значение за последние 30 дней (в том числе сегодня - отсюда вычитание 29 с сегодняшнего дня) – Kickstart

+0

Это больше похоже на это; ОП немного расплывчата в том, как именно считать 30. IFNULL? Ну, я думаю, это экономит на вводе! – Strawberry

+0

Я принял это за 30 дней до каждого дня. Думайте, что вы приняли это как до 30 дней с первого дня 30 дней назад для среднего (следовательно, на 2015-11-06 вы получаете 0.2174, что составляет 5 в среднем за 23 дня). Что касается IFNULL, если это всего лишь один возможный столбец, это то, что я обычно использовал; для меня это более интуитивно (и я серьезно сомневаюсь, что производительность полезнее). – Kickstart