2016-08-22 1 views
1

part_id가있는 마지막 두 배치에 대한 각 part_id의 평균 시간과 모든 배치에 대한 각 part_id의 평균 시간을 계산하려고합니다 .개별 그룹 세트에 속한 마지막 x 레코드의 평균 계산

발견 된 마지막 2 배치에 대한 part_id의 평균을 분리 할 수 ​​있었지만 각 부품 ID에 대한 계산을 수행 할 수 있도록 코드에 통합 할 수 없습니다. 알 수없는 열 'tst.part_id'에서 'where 절'에 오류가 발생했습니다.이 중첩 된 선택 쿼리에 해당 tst.part_id 값을 전달해야합니다.

part_id AVG on last 2 batches Average Time Overall 

1   27.25     25.67 

2   22.5      22.5 

3   16.67     16.67 

4   47.5      47.5 

테이블 스키마 :

여기
SELECT tst.part_id, 
    AVG(tst.est_time) AS 'Average Time Overall', 

(SELECT AVG(ft.avgLastMax) 
FROM 
(SELECT t2.avglst as 'avgLastMax', t2.numval as 'numval' 
FROM (SELECT 
     @num:=CASE WHEN @last != tst3.batch_id 
     THEN @num:=(@num + 1) 
     ELSE @num:[email protected] END 'numval', 
     @last:=tst3.batch_id, 
     @name:=CASE WHEN @num > 2 
     THEN @name:[email protected] 
     ELSE @name:=(tst3.est_time) END 'avglst' 
     FROM test AS tst3, 
     (select @last:=0, @avg := 0, @name :=0 , @num :=0) var 
     /* GET AVERAGE FOR A SINGLE PART ID 
     WHERE tst3.part_id = 1 */ 
     WHERE tst3.part_id = tst.part_id 
     ORDER BY tst3.run_id DESC) as t2 

) 
as ft 
WHERE ft.numval <3) as 'AVG on last 2 batches' 

FROM test AS tst 
GROUP BY tst.part_id; 

내가 얻으려고 노력하고있는 무슨이다 :

http://sqlfiddle.com/#!9/77bea5/85

쿼리 내가 사용 : 아래

내가 가진 바이올린입니다 :

CREATE TABLE test 
    (`part_id` int, `est_time` int, `batch_id` int, `run_id` int, `line` varchar(1)) 
; 

INSERT INTO test 
    (`part_id`, `est_time`, `batch_id`, `run_id`, `line`) 
VALUES 
    (1, 20, 1, 1, 'T'), 
    (1, 25, 1, 2, 'T'), 
    (2, 30, 1, 3, 'T'), 
    (3, 15, 1, 4, 'T'), 
    (1, 10, 2, 5, 'X'), 
    (4, 40, 2, 8, 'X'), 
    (2, 15, 3, 9, 'T'), 
    (3, 15, 3, 10, 'T'), 
    (3, 20, 3, 11, 'T'), 
    (1, 34, 4, 12, 'X'), 
    (1, 32, 4, 13, 'X'), 
    (1, 33, 4, 14, 'X'), 
    (4, 55, 5, 15, 'T') 
; 

EDITED : 마지막 batch_id를 가져 오기 위해 tst3.run_id DESC에 의해 표와 순서가 수정되었습니다. 변수

+0

숫자 귀하의 예상 출력에서 ​​합산하지 않는 것 같습니다. 예를 들어,'part_id' 1은 가장 최근의 두 개의 배치에 대해 평균이 32.5입니다. –

+0

실수로 순서를 거꾸로했는데 part_id 1의 경우 27.25가되어야합니다. ((33 + 32 + 34 + 10)/4) – barracuda

+0

(part_id, batch_id, run_id)은 고유/기본 항목입니다. 맞습니까? – Strawberry

답변

0
SELECT W.*,T1.ALLAVG 
FROM (
SELECT V.PART_ID, AVG(V.EST_TIME) LAST2 FROM 
(
SELECT U.PART_ID,U.MAXRN,X.RUN_ID,X.EST_TIME 
FROM 
(
/*LAST 2*/ 
SELECT S.PART_ID,MAX(S.RN) MAXRN 
FROM 
(
/*DERIVE A ROW NUMBER*/ 
SELECT T.PART_ID , T.RUN_ID, 
     IF (CONCAT(T.PART_ID,T.RUN_ID) <> @R ,@RN:[email protected]+1,@RN:=1) RN, 
     @R:=CONCAT(T.PART_ID,T.RUN_ID) R 
FROM  (SELECT @RN:=0,@P:=0,@R:=0) RN, TEST T 
ORDER BY T.PART_ID,T.RUN_ID 
) S 
GROUP BY S.PART_ID 
) U 

/*USING THE MAX ABOVE GET THE LAST 2 */ 
JOIN 

(SELECT T.PART_ID , T.RUN_ID,T.EST_TIME, 
     IF (CONCAT(T.PART_ID,T.RUN_ID) <> @R1 ,@RN1:[email protected]+1,@RN1:=1) RN, 
      @R1:=CONCAT(T.PART_ID,T.RUN_ID) R 
FROM  (SELECT @RN1:=0,@P1:=0,@R1:=0) RN, TEST T 
ORDER BY T.PART_ID,T.RUN_ID 

) X ON X.PART_ID = U.PART_ID AND (X.RN BETWEEN U.MAXRN -1 AND U.MAXRN) #AMEND THIS FOR THE LAST N REQUIRED 
) V 
GROUP BY V.PART_ID 
) W 
JOIN 
/*ALL*/ 
(SELECT T.PART_ID,AVG(T.EST_TIME) 'ALLAVG' FROM TEST T GROUP BY T.PART_ID) T1 ON T1.PART_ID = W.PART_ID 

결과

+---------+---------+---------+ 
| PART_ID | LAST2 | ALLAVG | 
+---------+---------+---------+ 
|  1 | 32.5000 | 25.6667 | 
|  2 | 22.5000 | 22.5000 | 
|  3 | 17.5000 | 16.6667 | 
|  4 | 47.5000 | 47.5000 | 
+---------+---------+---------+ 
1

첫 번째 결과가 잘못 가정 ...

SELECT a.part_id 
    , AVG(a.est_time) 
    FROM test a 
    JOIN 
    (SELECT x.part_id 
      , x.batch_id 
     FROM 
      (SELECT DISTINCT part_id 
          , batch_id 
         FROM test 
      ) x 
     JOIN 
      (SELECT DISTINCT part_id 
          , batch_id 
         FROM test 
      ) y 
      ON y.part_id = x.part_id 
      AND y.batch_id >= x.batch_id 
     GROUP 
      BY x.part_id 
      , x.batch_id 
     HAVING COUNT(*) <= 2 
    ) b 
    ON b.part_id = a.part_id 
    AND b.batch_id = a.batch_id 
GROUP 
    BY a.part_id; 
+---------+-----------------+ 
| part_id | AVG(a.est_time) | 
+---------+-----------------+ 
|  1 |   27.2500 | 
|  2 |   22.5000 | 
|  3 |   16.6667 | 
|  4 |   47.5000 | 
+---------+-----------------+ 

또는, 더 빨리 ... ...

SELECT part_id 
    , AVG(est_time) last_2_avg 
    FROM 
    (SELECT x.* 
      , CASE WHEN @part_id = part_id 
        THEN CASE WHEN @batch_id = batch_id THEN @i:[email protected] ELSE @i:[email protected]+1 END 
        ELSE @i:=1 
        END i 
      , @part_id := part_id 
      , @batch_id:= batch_id 
     FROM test x 
      , (SELECT @part_id := null, @batch_id:=null, @i:=1) vars 
     ORDER 
      BY part_id 
      , batch_id DESC 
    ) a 
WHERE a.i <= 2 
GROUP 
    BY part_id; 

+---------+------------+ 
| part_id | last_2_avg | 
+---------+------------+ 
|  1 | 27.2500 | 
|  2 | 22.5000 | 
|  3 | 16.6667 | 
|  4 | 47.5000 | 
+---------+------------+ 
+0

내 결과가 잘못되었습니다. 1에 대해 27.25입니다. – barracuda

+0

마지막 2 번에 대한 계산이 정확하며 코드보다 훨씬 깔끔합니다. 나는 평균 시간이이 결과를 이끈 조인해야 할 것이다 – barracuda