2016-08-22 10 views
1

part_idが見つかった最後の2つのバッチの各part_idの平均時間と、すべてのバッチの各part_idの平均時間を計算しようとしています。個別グループセットに属する最後のxレコードの平均を計算

最後に見つけた2つのバッチのpart_idのAverageを分離することができましたが、各パーツIDの計算を行うようにコードに統合することはできません。エラーが発生しました 'where句'の 'tst.part_id'列が不明です。そのtst.part_id値をネストされた選択クエリに渡す必要があります。

以下

私が持っているフィドルです:私が使用しています

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

問合せ:

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; 

をここでは私が取得しようとしていますものです:

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 

表スキーマ:

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を取得するために、DESCによってtst3.run_idによってテーブルと順序が訂正されました。変数と

+0

番号あなたの予想される出力では、加算されていないようです。例えば、 'part_id' 1は2つの直近のバッチに対して平均で' 32.5 'のようです。 –

+0

私は間違って注文を裏返しましたが、part_id 1の場合は27.25でなければなりません。((33 + 32 + 34 + 10)/ 4) – barracuda

+0

(part_id、batch_id、run_id)はUNIQUE/PRIMARYです。 – 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 

RESULT

+---------+---------+---------+ 
| 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