복붙노트

[SQL] 이동 평균 MySQL을 계산?

SQL

이동 평균 MySQL을 계산?

좋은 날,

나는 9 일 평균 이동 계산하기 위해 다음 코드를 사용하고 있습니다.

SELECT SUM(close)
FROM tbl
WHERE date <= '2002-07-05'
AND name_id = 2
ORDER BY date DESC
LIMIT 9

한계를 호출하기 전에 먼저 반환 된 모든 필드를 계산하기 때문에 그러나 그것은 작동하지 않습니다. 즉 그것은 모든 닫히고을 계산합니다 해당 날짜 이전에 동일하고 다만 지난 9.

내가 합계를 계산해야합니다 그래서 선택이 아니라 바로 계산을 반환에서.

IE. 선택 (SELECT)에서 SUM을 선택 ...

이제 어떻게이 일에 대해 가서 매우 비용이 많이 드는 또는 더 나은 방법이 것?

해결법

  1. ==============================

    1.같은 사용 뭔가

    같은 사용 뭔가

    SELECT 
      sum(close) as sum,
      avg(close) as average
    FROM (
        SELECT 
          (close)
        FROM 
          tbl
        WHERE 
          date <= '2002-07-05'
          AND name_id = 2
        ORDER BY 
          date DESC
        LIMIT 9 ) temp
    

    내부 쿼리는 내림차순 순서로 필터링 된 모든 행을 반환하고 당신은 평균, 반환 된 행을 요약.

    당신에 의해 주어진 질의하지 작업을 수행하는 이유는 합이 먼저 계산되고 합계가 이미 계산 된 후에 LIMIT 절은 당신에게 모든 행 존재의 합을주고, 적용되기 때문입니다

  2. ==============================

    2.각 날짜에 대한 이동 평균을 원한다면,이 시도 :

    각 날짜에 대한 이동 평균을 원한다면,이 시도 :

    SELECT date, SUM(close),
           (select avg(close) from tbl t2 where t2.name_id = t.name_id and datediff(t2.date, t.date) <= 9
           ) as mvgAvg
    FROM tbl t
    WHERE date <= '2002-07-05' and
          name_id = 2
    GROUP BY date
    ORDER BY date DESC
    

    이것은 9 개 값의 평균을 계산하는 상관 서브 쿼리를 사용한다.

  3. ==============================

    3.이 쿼리는 빠르고 :

    이 쿼리는 빠르고 :

    select date, name_id,
    case @i when name_id then @i:=name_id else (@i:=name_id)
    and (@n:=0)
    and (@a0:=0) and (@a1:=0) and (@a2:=0) and (@a3:=0) and (@a4:=0) and (@a5:=0) and (@a6:=0) and (@a7:=0) and (@a8:=0)
    end as a,
    case @n when 9 then @n:=9 else @n:=@n+1 end as n,
    @a0:=@a1,@a1:=@a2,@a2:=@a3,@a3:=@a4,@a4:=@a5,@a5:=@a6,@a6:=@a7,@a7:=@a8,@a8:=close,
    (@a0+@a1+@a2+@a3+@a4+@a5+@a6+@a7+@a8)/@n as av
    from tbl,
    (select @i:=0, @n:=0,
            @a0:=0, @a1:=0, @a2:=0, @a3:=0, @a4:=0, @a5:=0, @a6:=0, @a7:=0, @a8:=0) a
    where name_id=2
    order by name_id, date
    

    당신은 50 개 또는 100 값 이상 평균해야하는 경우 쓰기에 지루하지만 노력할 가치가있는. 속도는이 선택 주문 가까이에 있습니다.

  4. ==============================

    4.타 기술은 테이블을하는 것입니다 :

    타 기술은 테이블을하는 것입니다 :

    CREATE TABLE `tinyint_asc` (
     `value` tinyint(3) unsigned NOT NULL default '0',
     PRIMARY KEY (value)
    ) ;
    ​
    INSERT INTO `tinyint_asc` VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15),(16),(17),(18),(19),(20),(21),(22),(23),(24),(25),(26),(27),(28),(29),(30),(31),(32),(33),(34),(35),(36),(37),(38),(39),(40),(41),(42),(43),(44),(45),(46),(47),(48),(49),(50),(51),(52),(53),(54),(55),(56),(57),(58),(59),(60),(61),(62),(63),(64),(65),(66),(67),(68),(69),(70),(71),(72),(73),(74),(75),(76),(77),(78),(79),(80),(81),(82),(83),(84),(85),(86),(87),(88),(89),(90),(91),(92),(93),(94),(95),(96),(97),(98),(99),(100),(101),(102),(103),(104),(105),(106),(107),(108),(109),(110),(111),(112),(113),(114),(115),(116),(117),(118),(119),(120),(121),(122),(123),(124),(125),(126),(127),(128),(129),(130),(131),(132),(133),(134),(135),(136),(137),(138),(139),(140),(141),(142),(143),(144),(145),(146),(147),(148),(149),(150),(151),(152),(153),(154),(155),(156),(157),(158),(159),(160),(161),(162),(163),(164),(165),(166),(167),(168),(169),(170),(171),(172),(173),(174),(175),(176),(177),(178),(179),(180),(181),(182),(183),(184),(185),(186),(187),(188),(189),(190),(191),(192),(193),(194),(195),(196),(197),(198),(199),(200),(201),(202),(203),(204),(205),(206),(207),(208),(209),(210),(211),(212),(213),(214),(215),(216),(217),(218),(219),(220),(221),(222),(223),(224),(225),(226),(227),(228),(229),(230),(231),(232),(233),(234),(235),(236),(237),(238),(239),(240),(241),(242),(243),(244),(245),(246),(247),(248),(249),(250),(251),(252),(253),(254),(255);
    

    당신은처럼 사용 할 수 있습니다 후 :

    select date_add(tbl.date, interval tinyint_asc.value day) as mydate, count(*), sum(myvalue)
    from tbl inner join tinyint_asc.value <= 30 -- for a 30 day moving average
    where date(date_add(o.created_at, interval tinyint_asc.value day)) between '2016-01-01' and current_date()
    group by mydate
    
  5. from https://stackoverflow.com/questions/16121023/calculating-a-moving-average-mysql by cc-by-sa and MIT license